From 3d653c3057133f209176f17ccac01c9145abd1fe Mon Sep 17 00:00:00 2001 From: LucasB25 <50886682+LucasB25@users.noreply.github.com> Date: Wed, 11 Sep 2024 20:12:27 +0200 Subject: [PATCH 1/4] fix data --- prisma/schema.prisma | 79 ++++++++++++++------------- src/database/server.ts | 120 +++++++++++++++++++---------------------- 2 files changed, 97 insertions(+), 102 deletions(-) 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/src/database/server.ts b/src/database/server.ts index 2850aa980..642656fb7 100644 --- a/src/database/server.ts +++ b/src/database/server.ts @@ -1,4 +1,4 @@ -import { type Dj, type Guild, type Playlist, PrismaClient, type Role, type Setup, type Song, type Stay } from "@prisma/client"; +import { type Dj, type Guild, type Playlist, PrismaClient, type Role, type Song, type Setup, type Stay } from "@prisma/client"; import config from "../config.js"; export default class ServerData { @@ -9,16 +9,15 @@ export default class ServerData { } public async get(guildId: string): Promise { - return ( - (await this.prisma.guild.findUnique({ - where: { guildId }, - })) ?? this.createGuild(guildId) - ); + 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 }, + data: { + guildId, + prefix: config.prefix, + }, }); } @@ -30,6 +29,39 @@ export default class ServerData { }); } + 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 }, @@ -42,6 +74,13 @@ export default class ServerData { 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 }, @@ -50,13 +89,6 @@ export default class ServerData { }); } - 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 } }); } @@ -77,36 +109,22 @@ export default class ServerData { 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) { + public async getUserPlaylists(userId: string): Promise { return await this.prisma.playlist.findMany({ - where: { - userId: userId, - }, + 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: { @@ -119,10 +137,6 @@ export default class ServerData { }); } - 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 } }, @@ -161,9 +175,7 @@ export default class ServerData { await this.prisma.song.deleteMany({ where: { playlistId: playlist.id, - track: { - contains: encodedSong, - }, + track: { contains: encodedSong }, }, }); } @@ -172,9 +184,7 @@ export default class ServerData { 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 this.prisma.song.findMany({ where: { playlistId: playlist.id } }); } return []; } @@ -182,9 +192,7 @@ export default class ServerData { 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 }, - }); + await this.prisma.song.deleteMany({ where: { playlistId: playlist.id } }); } } @@ -199,24 +207,6 @@ export default class ServerData { 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; - } } /** From f7913a49e1b4726dc5e4510cc39cb28fd386a3b7 Mon Sep 17 00:00:00 2001 From: hwangsihu Date: Sun, 8 Sep 2024 23:20:53 +0900 Subject: [PATCH 2/4] Update languages Update korean config.ts Update Shoukaku package.json config.ts Update Buttons Typescript updatee Changed the button order again Update typescript and biome, formatting Update TypeScript Remove empty block Format fix data Format again --- biome.json | 13 +- locales/Bulgarian.json | 2 +- locales/Croatian.json | 2 +- locales/Czech.json | 2 +- locales/Danish.json | 2 +- locales/Dutch.json | 2 +- locales/EnglishGB.json | 2 +- locales/EnglishUS.json | 2 +- locales/Finnish.json | 2 +- locales/Greek.json | 2 +- locales/Hungarian.json | 2 +- locales/Italian.json | 2 +- locales/Korean.json | 30 +- locales/Lithuanian.json | 2 +- locales/PortugueseBR.json | 2 +- locales/Romanian.json | 2 +- locales/Swedish.json | 2 +- locales/Thai.json | 2 +- locales/Turkish.json | 2 +- locales/Ukrainian.json | 2 +- package.json | 15 +- prisma/schema.prisma | 79 ++-- scripts/clean.js | 16 +- scripts/restart.ts | 18 +- src/LavaClient.ts | 4 +- src/commands/config/247.ts | 126 +++--- src/commands/config/Dj.ts | 338 +++++++------- src/commands/config/Language.ts | 246 +++++----- src/commands/config/Prefix.ts | 196 ++++---- src/commands/config/Setup.ts | 328 +++++++------- src/commands/dev/CreateInvite.ts | 112 +++-- src/commands/dev/DeleteInvites.ts | 78 ++-- src/commands/dev/Deploy.ts | 176 +++---- src/commands/dev/Eval.ts | 130 +++--- src/commands/dev/GuildLeave.ts | 124 ++--- src/commands/dev/GuildList.ts | 82 ++-- src/commands/dev/Restart.ts | 126 +++--- src/commands/filters/8d.ts | 108 ++--- src/commands/filters/BassBoost.ts | 118 ++--- src/commands/filters/Distorsion.ts | 126 +++--- src/commands/filters/Karaoke.ts | 118 ++--- src/commands/filters/LowPass.ts | 108 ++--- src/commands/filters/NightCore.ts | 108 ++--- src/commands/filters/Pitch.ts | 126 +++--- src/commands/filters/Rate.ts | 126 +++--- src/commands/filters/Reset.ts | 82 ++-- src/commands/filters/Rotation.ts | 106 ++--- src/commands/filters/Speed.ts | 126 +++--- src/commands/filters/Tremolo.ts | 108 ++--- src/commands/filters/Vibrato.ts | 108 ++--- src/commands/info/About.ts | 152 +++---- src/commands/info/Botinfo.ts | 138 +++--- src/commands/info/Help.ts | 201 ++++---- src/commands/info/Invite.ts | 88 ++-- src/commands/info/LavaLink.ts | 148 +++--- src/commands/info/Ping.ts | 124 ++--- src/commands/music/Autoplay.ts | 100 ++-- src/commands/music/ClearQueue.ts | 92 ++-- src/commands/music/Grab.ts | 128 +++--- src/commands/music/Join.ts | 132 +++--- src/commands/music/Leave.ts | 82 ++-- src/commands/music/Loop.ts | 100 ++-- src/commands/music/Nowplaying.ts | 112 ++--- src/commands/music/Pause.ts | 82 ++-- src/commands/music/Play.ts | 340 +++++++------- src/commands/music/PlayNext.ts | 330 +++++++------- src/commands/music/Queue.ts | 156 ++++--- src/commands/music/Remove.ts | 116 ++--- src/commands/music/Replay.ts | 82 ++-- src/commands/music/Resume.ts | 82 ++-- src/commands/music/Search.ts | 220 ++++----- src/commands/music/Seek.ts | 142 +++--- src/commands/music/Shuffle.ts | 80 ++-- src/commands/music/Skip.ts | 102 ++--- src/commands/music/Skipto.ts | 110 ++--- src/commands/music/Stop.ts | 74 +-- src/commands/music/Volume.ts | 120 ++--- src/commands/playlist/AddSong.ts | 264 +++++------ src/commands/playlist/Create.ts | 124 ++--- src/commands/playlist/Delete.ts | 144 +++--- src/commands/playlist/List.ts | 224 ++++----- src/commands/playlist/Load.ts | 198 ++++---- src/commands/playlist/RemoveSong.ts | 216 ++++----- src/commands/playlist/Steal.ts | 356 +++++++-------- src/config.ts | 138 +++--- src/database/server.ts | 420 +++++++++-------- src/events/client/ChannelDelete.ts | 61 ++- src/events/client/GuildCreate.ts | 122 ++--- src/events/client/GuildDelete.ts | 122 ++--- src/events/client/InteractionCreate.ts | 433 +++++++++--------- src/events/client/MessageCreate.ts | 438 +++++++++--------- src/events/client/Ready.ts | 48 +- src/events/client/SetupButtons.ts | 434 +++++++++--------- src/events/client/SetupSystem.ts | 98 ++-- src/events/client/VoiceStateUpdate.ts | 120 ++--- src/events/player/NodeConnect.ts | 68 ++- src/events/player/NodeDestroy.ts | 34 +- src/events/player/NodeDisconnect.ts | 20 +- src/events/player/NodeError.ts | 22 +- src/events/player/NodeRaw.ts | 18 +- src/events/player/NodeReconnect.ts | 20 +- src/events/player/QueueEnd.ts | 58 +-- src/events/player/TrackEnd.ts | 52 +-- src/events/player/TrackStart.ts | 434 +++++++++--------- src/index.ts | 56 +-- src/plugin/index.ts | 32 +- src/plugin/plugins/antiCrash.ts | 44 +- src/plugin/plugins/keepAlive.ts | 28 +- src/plugin/plugins/updateStatus.ts | 12 +- src/structures/Command.ts | 138 +++--- src/structures/Context.ts | 224 ++++----- src/structures/Dispatcher.ts | 497 ++++++++++---------- src/structures/Event.ts | 34 +- src/structures/I18n.ts | 52 +-- src/structures/Lavamusic.ts | 370 ++++++++------- src/structures/Logger.ts | 96 ++-- src/structures/Queue.ts | 126 +++--- src/structures/Shoukaku.ts | 68 +-- src/types.ts | 140 +++--- src/utils/BotLog.ts | 28 +- src/utils/Buttons.ts | 130 +++--- src/utils/SetupSystem.ts | 604 ++++++++++++------------- src/utils/ThemeSelector.ts | 122 ++--- src/utils/Utils.ts | 298 ++++++------ tsconfig.json | 7 +- 125 files changed, 7543 insertions(+), 7623 deletions(-) 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, From 4f23323d06e23fa0a7745fa15e7f29ad5464d13d Mon Sep 17 00:00:00 2001 From: hwangsihu Date: Thu, 12 Sep 2024 23:57:22 +0900 Subject: [PATCH 3/4] Format for resolving conflicts --- biome.json | 138 +++--- package.json | 110 ++--- process.json | 16 +- scripts/clean.js | 16 +- scripts/restart.ts | 18 +- src/LavaClient.ts | 4 +- src/commands/config/247.ts | 126 +++--- src/commands/config/Dj.ts | 338 +++++++------- src/commands/config/Language.ts | 246 +++++----- src/commands/config/Prefix.ts | 196 ++++---- src/commands/config/Setup.ts | 328 +++++++------- src/commands/dev/CreateInvite.ts | 112 ++--- src/commands/dev/DeleteInvites.ts | 78 ++-- src/commands/dev/Deploy.ts | 176 +++---- src/commands/dev/Eval.ts | 130 +++--- src/commands/dev/GuildLeave.ts | 124 ++--- src/commands/dev/GuildList.ts | 82 ++-- src/commands/dev/Restart.ts | 126 +++--- src/commands/filters/8d.ts | 108 ++--- src/commands/filters/BassBoost.ts | 118 ++--- src/commands/filters/Distorsion.ts | 126 +++--- src/commands/filters/Karaoke.ts | 118 ++--- src/commands/filters/LowPass.ts | 108 ++--- src/commands/filters/NightCore.ts | 108 ++--- src/commands/filters/Pitch.ts | 126 +++--- src/commands/filters/Rate.ts | 126 +++--- src/commands/filters/Reset.ts | 82 ++-- src/commands/filters/Rotation.ts | 106 ++--- src/commands/filters/Speed.ts | 126 +++--- src/commands/filters/Tremolo.ts | 108 ++--- src/commands/filters/Vibrato.ts | 108 ++--- src/commands/info/About.ts | 152 +++---- src/commands/info/Botinfo.ts | 138 +++--- src/commands/info/Help.ts | 201 ++++---- src/commands/info/Invite.ts | 88 ++-- src/commands/info/LavaLink.ts | 148 +++--- src/commands/info/Ping.ts | 124 ++--- src/commands/music/Autoplay.ts | 100 ++-- src/commands/music/ClearQueue.ts | 92 ++-- src/commands/music/Grab.ts | 128 +++--- src/commands/music/Join.ts | 132 +++--- src/commands/music/Leave.ts | 82 ++-- src/commands/music/Loop.ts | 100 ++-- src/commands/music/Nowplaying.ts | 112 ++--- src/commands/music/Pause.ts | 82 ++-- src/commands/music/Play.ts | 340 +++++++------- src/commands/music/PlayNext.ts | 330 +++++++------- src/commands/music/Queue.ts | 156 +++---- src/commands/music/Remove.ts | 116 ++--- src/commands/music/Replay.ts | 82 ++-- src/commands/music/Resume.ts | 82 ++-- src/commands/music/Search.ts | 220 ++++----- src/commands/music/Seek.ts | 142 +++--- src/commands/music/Shuffle.ts | 80 ++-- src/commands/music/Skip.ts | 102 ++--- src/commands/music/Skipto.ts | 110 ++--- src/commands/music/Stop.ts | 74 +-- src/commands/music/Volume.ts | 120 ++--- src/commands/playlist/AddSong.ts | 264 +++++------ src/commands/playlist/Create.ts | 124 ++--- src/commands/playlist/Delete.ts | 144 +++--- src/commands/playlist/List.ts | 224 ++++----- src/commands/playlist/Load.ts | 198 ++++---- src/commands/playlist/RemoveSong.ts | 216 ++++----- src/commands/playlist/Steal.ts | 356 ++++++++------- src/config.ts | 138 +++--- src/database/server.ts | 410 ++++++++--------- src/events/client/ChannelDelete.ts | 61 +-- src/events/client/GuildCreate.ts | 122 ++--- src/events/client/GuildDelete.ts | 122 ++--- src/events/client/InteractionCreate.ts | 433 +++++++++--------- src/events/client/MessageCreate.ts | 438 +++++++++--------- src/events/client/Ready.ts | 48 +- src/events/client/SetupButtons.ts | 434 +++++++++--------- src/events/client/SetupSystem.ts | 98 ++-- src/events/client/VoiceStateUpdate.ts | 120 ++--- src/events/player/NodeConnect.ts | 68 +-- src/events/player/NodeDestroy.ts | 34 +- src/events/player/NodeDisconnect.ts | 20 +- src/events/player/NodeError.ts | 22 +- src/events/player/NodeRaw.ts | 18 +- src/events/player/NodeReconnect.ts | 20 +- src/events/player/QueueEnd.ts | 58 +-- src/events/player/TrackEnd.ts | 52 +-- src/events/player/TrackStart.ts | 434 +++++++++--------- src/index.ts | 56 +-- src/plugin/index.ts | 32 +- src/plugin/plugins/antiCrash.ts | 44 +- src/plugin/plugins/keepAlive.ts | 28 +- src/plugin/plugins/updateStatus.ts | 12 +- src/structures/Command.ts | 138 +++--- src/structures/Context.ts | 224 ++++----- src/structures/Dispatcher.ts | 497 ++++++++++---------- src/structures/Event.ts | 34 +- src/structures/I18n.ts | 52 +-- src/structures/Lavamusic.ts | 370 +++++++-------- src/structures/Logger.ts | 96 ++-- src/structures/Queue.ts | 126 +++--- src/structures/Shoukaku.ts | 68 +-- src/types.ts | 140 +++--- src/utils/BotLog.ts | 28 +- src/utils/Buttons.ts | 130 +++--- src/utils/SetupSystem.ts | 604 +++++++++++++------------ src/utils/ThemeSelector.ts | 122 ++--- src/utils/Utils.ts | 298 ++++++------ tsconfig.json | 38 +- 106 files changed, 7667 insertions(+), 7611 deletions(-) diff --git a/biome.json b/biome.json index 86ea89a20..fc1aafd72 100644 --- a/biome.json +++ b/biome.json @@ -1,74 +1,74 @@ { - "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "all": true, - "suspicious": { - "noConfusingVoidType": "off", - "noConsoleLog": "off", - "noEmptyBlockStatements": "off", - "noExplicitAny": "off", - "noGlobalIsFinite": "off", - "noGlobalIsNan": "off", - "useAwait": "off" - }, - "style": { - "noDefaultExport": "off", - "noInferrableTypes": "off", - "noNamespaceImport": "off", - "noNonNullAssertion": "off", - "noParameterAssign": "off", - "useBlockStatements": "off", - "useFilenamingConvention": "off", - "useNamingConvention": "off", - "useNumberNamespace": "off", - "useSingleCaseStatement": "off" - }, - "complexity": { - "noBannedTypes": "off", - "noForEach": "off", - "noStaticOnlyClass": "off", - "noExcessiveCognitiveComplexity": { - "level": "warn", - "options": { - "maxAllowedComplexity": 255 - } + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "all": true, + "suspicious": { + "noConfusingVoidType": "off", + "noConsoleLog": "off", + "noEmptyBlockStatements": "off", + "noExplicitAny": "off", + "noGlobalIsFinite": "off", + "noGlobalIsNan": "off", + "useAwait": "off" + }, + "style": { + "noDefaultExport": "off", + "noInferrableTypes": "off", + "noNamespaceImport": "off", + "noNonNullAssertion": "off", + "noParameterAssign": "off", + "useBlockStatements": "off", + "useFilenamingConvention": "off", + "useNamingConvention": "off", + "useNumberNamespace": "off", + "useSingleCaseStatement": "off" + }, + "complexity": { + "noBannedTypes": "off", + "noForEach": "off", + "noStaticOnlyClass": "off", + "noExcessiveCognitiveComplexity": { + "level": "warn", + "options": { + "maxAllowedComplexity": 255 + } + } + }, + "security": { + "noGlobalEval": "off" + }, + "correctness": { + "noNodejsModules": "off", + "noVoidTypeReturn": "off" + }, + "performance": { + "noBarrelFile": "off" + } } - }, - "security": { - "noGlobalEval": "off" - }, - "correctness": { - "noNodejsModules": "off", - "noVoidTypeReturn": "off" - }, - "performance": { - "noBarrelFile": "off" - } - } - }, - "formatter": { - "enabled": true, - "indentWidth": 2, - "indentStyle": "space", - "lineEnding": "crlf", - "lineWidth": 140, - "formatWithErrors": true - }, - "javascript": { + }, "formatter": { - "quoteStyle": "double", - "arrowParentheses": "always", - "bracketSameLine": true, - "semicolons": "always" + "enabled": true, + "indentWidth": 4, + "indentStyle": "space", + "lineEnding": "crlf", + "lineWidth": 140, + "formatWithErrors": true + }, + "javascript": { + "formatter": { + "quoteStyle": "double", + "arrowParentheses": "always", + "bracketSameLine": true, + "semicolons": "always" + } + }, + "files": { + "ignoreUnknown": false, + "ignore": [".vscode", "dist", "locales", "node_modules"] } - }, - "files": { - "ignoreUnknown": false, - "ignore": [".vscode", "dist", "locales", "node_modules"] - } } diff --git a/package.json b/package.json index 9ba6624fa..cfc04ee6e 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,57 @@ { - "name": "lavamusic", - "version": "4.6.7", - "description": "LavaMusic is a music bot for Discord, written in JavaScript using the Discord.js, Typescript, Shoukaku (Lavalink) library.", - "main": "dist/index.js", - "type": "module", - "scripts": { - "start": "npm run clean && node .", - "db:push": "npx prisma db push", - "db:migrate": "npx prisma migrate dev --name init", - "build": "tsc --project tsconfig.json", - "clean": "node scripts/clean.js && npm run build", - "lint": "biome lint --write", - "format": "biome format --write" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/appujet/lavamusic.git" - }, - "keywords": ["discord", "music", "bot", "lavalink", "shoukaku", "lavamusic", "typescript", "prisma"], - "author": "appujet", - "license": "GPL-3.0", - "bugs": { - "url": "https://github.com/appujet/lavamusic/issues" - }, - "homepage": "https://github.com/appujet/lavamusic#readme", - "devDependencies": { - "@biomejs/biome": "^1.8.3", - "@types/i18n": "^0.13.12", - "@types/node": "^22.5.4", - "@types/signale": "^1.4.7", - "prisma": "^5.19.1", - "typescript": "^5.6.2" - }, - "dependencies": { - "@prisma/client": "^5.19.1", - "@top-gg/sdk": "^3.1.6", - "discord.js": "^14.16.1", - "dotenv": "^16.4.5", - "i18n": "^0.15.1", - "node-system-stats": "^1.3.0", - "shoukaku": "^4.1.1", - "signale": "^1.4.0", - "topgg-autoposter": "^2.0.2", - "tslib": "^2.7.0", - "undici": "^6.19.8" - }, - "signale": { - "displayScope": true, - "displayBadge": true, - "displayDate": true, - "displayFilename": true, - "displayLabel": true, - "displayTimestamp": true, - "underlineLabel": true - } + "name": "lavamusic", + "version": "4.6.7", + "description": "LavaMusic is a music bot for Discord, written in JavaScript using the Discord.js, Typescript, Shoukaku (Lavalink) library.", + "main": "dist/index.js", + "type": "module", + "scripts": { + "start": "npm run clean && node .", + "db:push": "npx prisma db push", + "db:migrate": "npx prisma migrate dev --name init", + "build": "tsc --project tsconfig.json", + "clean": "node scripts/clean.js && npm run build", + "lint": "biome lint --write", + "format": "biome format --write" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/appujet/lavamusic.git" + }, + "keywords": ["discord", "music", "bot", "lavalink", "shoukaku", "lavamusic", "typescript", "prisma"], + "author": "appujet", + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/appujet/lavamusic/issues" + }, + "homepage": "https://github.com/appujet/lavamusic#readme", + "devDependencies": { + "@biomejs/biome": "^1.8.3", + "@types/i18n": "^0.13.12", + "@types/node": "^22.5.4", + "@types/signale": "^1.4.7", + "prisma": "^5.19.1", + "typescript": "^5.6.2" + }, + "dependencies": { + "@prisma/client": "^5.19.1", + "@top-gg/sdk": "^3.1.6", + "discord.js": "^14.16.1", + "dotenv": "^16.4.5", + "i18n": "^0.15.1", + "node-system-stats": "^1.3.0", + "shoukaku": "^4.1.1", + "signale": "^1.4.0", + "topgg-autoposter": "^2.0.2", + "tslib": "^2.7.0", + "undici": "^6.19.8" + }, + "signale": { + "displayScope": true, + "displayBadge": true, + "displayDate": true, + "displayFilename": true, + "displayLabel": true, + "displayTimestamp": true, + "underlineLabel": true + } } diff --git a/process.json b/process.json index bda8eaceb..7f2115ba3 100644 --- a/process.json +++ b/process.json @@ -1,10 +1,10 @@ { - "apps": [ - { - "name": "lavamusic", - "script": "dist/index.js", - "node_args": ["--enable-source-maps"], - "restart_delay": 10000 - } - ] + "apps": [ + { + "name": "lavamusic", + "script": "dist/index.js", + "node_args": ["--enable-source-maps"], + "restart_delay": 10000 + } + ] } diff --git a/scripts/clean.js b/scripts/clean.js index 76de41728..4ce4104c4 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 }); + 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); } - } 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 540ed1763..f2ba2a50f 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 8972bbac0..2c1663f04 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 eab0e7c69..25e8d5f31 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: [], - }); - } - - 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)], + 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: [], }); - } - 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 71d5943d8..2cafdaf6e 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", - }, - 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, + 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", }, - ], - }, - { - name: "remove", - description: "cmd.dj.options.remove", - 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: "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; - - 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]); - } - - 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, - }), - ), + 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, + }, ], - }); - } - 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 "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, - }), - ), - ], - }); + 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; - case "clear": - if (!dj) { - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.dj.errors.no_roles"))], - }); + 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]); } - await client.db.clearRoles(ctx.guild!.id); - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.dj.messages.all_roles_cleared"))], - }); - 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", - }), - ), - ], - }); + 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, + }), + ), + ], + }); - 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 "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 "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 "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 d7c468017..050160751 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", - }, - 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, + constructor(client: Lavamusic) { + super(client, { + name: "language", + description: { + content: "cmd.language.description", + examples: ["language set `EnglishUS`", "language reset"], + usage: "language", }, - ], - }, - { - 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(); + 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, + }, + ], + }); } - if (subCommand === "set") { - const embed = client.embed().setColor(this.client.color.main); - const locale = await client.db.getLanguage(ctx.guild!.id); + 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); - let lang: string; + const locale = await client.db.getLanguage(ctx.guild!.id); - 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 ? "" : " "); + if (ctx.isInteraction) { + lang = ctx.interaction.options.data[0].options[0].value as string; + } else { + lang = args[0]; + } + + 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, + }), + ), + ], + }); } - 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; + if (locale && locale === lang) { + return ctx.sendMessage({ + embeds: [ + embed.setDescription( + ctx.locale("cmd.language.already_set", { + language: 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); + await client.db.updateLanguage(ctx.guild!.id, lang); + ctx.guildLocale = lang; - const locale = await client.db.getLanguage(ctx.guild!.id); + 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); - if (!locale) { - return ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.language.not_set"))], - }); - } + const locale = await client.db.getLanguage(ctx.guild!.id); - await client.db.updateLanguage(ctx.guild!.id, Language.EnglishUS); - ctx.guildLocale = Language.EnglishUS; + 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; - 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 2e62d78a3..b745b03bd 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", - }, - 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, + constructor(client: Lavamusic) { + super(client, { + name: "prefix", + description: { + content: "cmd.prefix.description", + examples: ["prefix set !", "prefix reset"], + usage: "prefix", }, - ], - }, - { - 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; - - 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] || ""; + 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, + }, + ], + }); } - 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] }); + 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 (prefix.length > 3) { - embed.setDescription(ctx.locale("cmd.prefix.errors.prefix_too_long")); - 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] }); + } } - 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 5a00baf2d..f261efd97 100644 --- a/src/commands/config/Setup.ts +++ b/src/commands/config/Setup.ts @@ -3,175 +3,179 @@ 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", - }, - 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, - ], + constructor(client: Lavamusic) { + super(client, { + name: "setup", + description: { + content: "cmd.setup.description", + examples: ["setup create", "setup delete", "setup info"], + usage: "setup", }, - { - type: OverwriteType.Role, - id: ctx.guild.roles.everyone.id, - allow: [PermissionFlagsBits.ViewChannel, PermissionFlagsBits.SendMessages, PermissionFlagsBits.ReadMessageHistory], + category: "config", + aliases: ["set"], + cooldown: 3, + args: true, + vote: true, + player: { + voice: false, + dj: false, + active: false, + djPerm: null, }, - ], - }); - 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, + permissions: { + dev: false, + client: ["SendMessages", "ReadMessageHistory", "ViewChannel", "EmbedLinks", "ManageChannels"], + user: ["ManageGuild"], }, - ], - }); - 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, - }, + 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, + }, ], - }); - } - 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, - }, - ], - }); + } + + 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; - } - default: - break; } - } } /** diff --git a/src/commands/dev/CreateInvite.ts b/src/commands/dev/CreateInvite.ts index 3d3c7d99f..fc0bcdfd1 100644 --- a/src/commands/dev/CreateInvite.ts +++ b/src/commands/dev/CreateInvite.ts @@ -2,67 +2,69 @@ 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 eb5a07881..c63e6f72d 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 602331a59..9203a3397 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: [], - }); - } - - 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; + 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: [], + }); } - 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, - }); - - 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); - } - }); + 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), + ); - collector.on("end", async (_collected, reason) => { - if (reason === "time" && msg) { + let msg: Message | undefined; try { - await msg.delete(); + msg = await ctx.sendMessage({ + content: "Where do you want to deploy the commands?", + components: [row], + }); } catch (error) { - console.error("Failed to delete the message:", 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 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("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 0d892149e..6f0e890fc 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 7080d017b..e08c6b65b 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 da01025a3..7d7373aa3 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 7f375b186..b670d582d 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 4f148f827..cf10b89d1 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 fec2d6289..75188421f 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 8fc84bcde..289588984 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 492bd3387..c41e3d358 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 04a23ac73..da33a65e9 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 febbea514..57cbae9d9 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 b6577113e..5cb2105d4 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, - }, - ], - }); - } + 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); + 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); - 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; - } + 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, - }, - ], - }); - } + 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 f197e3826..f9e1733d3 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, - }, - ], - }); - } + 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); + 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); - 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; - } + 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, - }, - ], - }); - } + 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 0ed54a649..cced01703 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 81f32bf41..6519a80d1 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 589ebf16b..cc467c539 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, - }, - ], - }); - } + 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); + 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); - 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; - } + 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, - }, - ], - }); - } + 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 56fd9e7db..0d31189a8 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 e9a3fced6..4dad08598 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 acca4ffd0..7865d9c01 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 2310b2e79..c4038bfea 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 d38d6f39b..eddcc5617 100644 --- a/src/commands/info/Help.ts +++ b/src/commands/info/Help.ts @@ -1,111 +1,112 @@ 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, - }, - ], - }); - } - - 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], - }), - ), - ], + 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, + }, + ], }); - } - 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, - })); + 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] }); + } - 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 fields = categories.map((category) => ({ + name: category, + value: commands + .filter((cmd) => cmd.category === category) + .map((cmd) => `\`${cmd.name}\``) + .join(", "), + inline: false, + })); - return await ctx.sendMessage({ embeds: [helpEmbed] }); - } + 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] }); + } } /** diff --git a/src/commands/info/Invite.ts b/src/commands/info/Invite.ts index 95952550f..3e222457f 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 63b1712df..feccfe55c 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 29567c512..298795cef 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 8ad972ec4..d3266b486 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 c0419ce24..3087c0f82 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: [], - }); - } + 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(); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - if (!player) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_player"))], - }); - } + if (!player) { + return await ctx.sendMessage({ + embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("player.errors.no_player"))], + }); + } - 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.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"))], - }); - } + 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 28e1b87c2..ee91ab13a 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 1e21789a9..7f2eab587 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 2a761bb0b..8673a86a8 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 }))], - }); + 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"))], + }); } - 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 84cf35429..f4b090424 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: [], - }); - } + 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 = ""; + 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 = ""; - 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; - } + 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)], - }); - } + return await ctx.sendMessage({ + embeds: [embed.setDescription(loopMessage)], + }); + } } /** diff --git a/src/commands/music/Nowplaying.ts b/src/commands/music/Nowplaying.ts index fcbf5f6cc..55766cceb 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 5107ede0b..48923906b 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 4e6a5f4de..fbf56afc3 100644 --- a/src/commands/music/Play.ts +++ b/src/commands/music/Play.ts @@ -3,181 +3,187 @@ 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); + 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; + } } - 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(); + 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) { - 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, - }); - }); - } - } + 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); - } + return await interaction.respond(songs).catch(console.error); + } } /** diff --git a/src/commands/music/PlayNext.ts b/src/commands/music/PlayNext.ts index 8c73455cb..6d0a9c83d 100644 --- a/src/commands/music/PlayNext.ts +++ b/src/commands/music/PlayNext.ts @@ -3,173 +3,185 @@ 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, - }, - ], - }); - } - - 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 })), + 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, + }, ], - }); - 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(); - const res = await this.client.queue.search(focusedValue); - const songs = []; + 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); - 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)}...`; + 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; + } } - songs.push({ - name: name, - value: x.info.uri, - }); - }); } + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); + + const res = await this.client.queue.search(focusedValue); + const songs = []; - return await interaction.respond(songs).catch(console.error); - } + 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, + }); + }); + } + + return await interaction.respond(songs).catch(console.error); + } } /** diff --git a/src/commands/music/Queue.ts b/src/commands/music/Queue.ts index 3fe7c4a04..a6707fcc7 100644 --- a/src/commands/music/Queue.ts +++ b/src/commands/music/Queue.ts @@ -1,87 +1,89 @@ 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: [], - }); - } - - 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), - }), - ); + 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: [], + }); } - let chunks = client.utils.chunk(songStrings, 10); - if (chunks.length === 0) chunks = [songStrings]; + 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); - 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, - }), + 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, + }), + }); }); - }); - 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 b18bbe0ec..5b1f60567 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 1e72a4b10..d1a32907d 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: [], - }); - } + 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(); + public async run(client: Lavamusic, ctx: Context): Promise { + const player = client.queue.get(ctx.guild!.id); + const embed = this.client.embed(); - if (!player.current?.info.isSeekable) { - return await ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.replay.errors.not_seekable"))], - }); - } + 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"))], - }); - } + 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 f8128d439..d55eddfa5 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: [], - }); - } + 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(); + 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("cmd.resume.errors.not_paused"))], - }); - } + 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"))], - }); - } + 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 eb1af762e..a26412b72 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, - }, - ], - }); - } - - 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)], - }); + 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, + }, + ], + }); } - 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"))], + + 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, }); - break; - case LoadType.EMPTY: - ctx.sendMessage({ - embeds: [embed.setColor(this.client.color.red).setDescription(ctx.locale("cmd.search.errors.no_results"))], + 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.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], + collector.on("end", async () => { + await ctx.editMessage({ components: [] }); }); - 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 d771f9736..f17c21489 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, - }, - ], - }); - } - - 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"))], - }); + 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, + }, + ], + }); } - 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), - }), - ), - ], - }); + + 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), + }), + ), + ], + }); } - 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 ff8af78ca..4328cde13 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"))], - }); + 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"))], + }); } - 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 99907f49f..057b415a5 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: [], - }); - } - - 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"))], - }); + 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: [], + }); } - 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, - }), - ), - ], - }); + + 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("👍"); } - ctx.message?.react("👍"); - } } /** diff --git a/src/commands/music/Skipto.ts b/src/commands/music/Skipto.ts index c64292f56..1ebb24623 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, - }, - ], - }); - } + 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]); + 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]); - 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"))], - }); - } + 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, - }), - ), - ], - }); - } + 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 4569dddc7..e8f97a802 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 c0f98ea39..36ef52acb 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 41e95af92..c4ef21ff3 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, - }, - ], - }); - } - - 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, - }, - ], - }); + 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, + }, + ], + }); } - 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 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, + }, + ], + }); } - 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, - }, - ], - }); - } + public async autocomplete(interaction: AutocompleteInteraction): Promise { + const focusedValue = interaction.options.getFocused(); + const userId = interaction.user.id; - 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; - } + const playlists = await this.client.db.getUserPlaylists(userId); - 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, - })), - ); - } + 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 57babb129..c6b80a7ea 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, - }, - ], - }); - } + 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(); + public async run(client: Lavamusic, ctx: Context, args: string[]): Promise { + const name = args.join(" ").trim(); + const embed = this.client.embed(); - if (name.length > 50) { - return await ctx.sendMessage({ - embeds: [embed.setDescription(ctx.locale("cmd.create.messages.name_too_long")).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)], + }); + } - 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)], - }); - } + 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), - ], - }); - } + 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 c99e32de6..663bd4518 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 28785f817..73e136c91 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 e495ce53c..f23cdd3cc 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, + }, + ], + }); + } + + 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/RemoveSong.ts b/src/commands/playlist/RemoveSong.ts index 8f11b5039..04c2e7201 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 d39f92fa9..c780c7a21 100644 --- a/src/commands/playlist/Steal.ts +++ b/src/commands/playlist/Steal.ts @@ -1,191 +1,197 @@ 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, - }, - 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, + constructor(client: Lavamusic) { + super(client, { + name: "steal", + description: { + content: "cmd.steal.description", + examples: ["steal <@user> "], + usage: "steal <@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, + 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, + }, + ], }); - } - - 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 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; - } + 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, + }, + ], + }); + } + } + } - const playlists = await this.client.db.getUserPlaylists(user.id); + if (!playlistName) { + return await ctx.sendMessage({ + embeds: [ + { + description: ctx.locale("cmd.steal.messages.provide_playlist"), + color: this.client.color.red, + }, + ], + }); + } - if (!playlists || playlists.length === 0) { - await interaction.respond([{ name: "No playlists found for this user.", value: "NoPlaylists" }]).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 filtered = playlists.filter((playlist) => playlist.name.toLowerCase().startsWith(focusedValue.toLowerCase())); + 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, + }, + ], + }); + } + } - 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); + 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); + } } - } } /** diff --git a/src/config.ts b/src/config.ts index 021447195..c7528a8ec 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, - }, - 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: "🔂", + token: process.env.TOKEN, + prefix: process.env.PREFIX, + color: { + red: 0xff0000, + green: 0x00ff00, + blue: 0x0000ff, + yellow: 0xffff00, + main: 0x2f3136, }, - page: { - last: "⏩", - first: "⏪", - back: "⬅️", - next: "➡️", - cancel: "⏹️", + 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: "🔂", + }, + 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 6f6df052f..1710a8321 100644 --- a/src/database/server.ts +++ b/src/database/server.ts @@ -2,211 +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 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(); - } + 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 e873a698f..1fc1ceeaf 100644 --- a/src/events/client/ChannelDelete.ts +++ b/src/events/client/ChannelDelete.ts @@ -1,39 +1,42 @@ 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; + 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); + } } - } - } 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 dff12b95e..e7b2a27e4 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", - }); - } - - 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}`); + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "guildCreate", + }); } - 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(); + 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 logChannelId = this.client.config.logChannelId; - if (!logChannelId) { - this.client.logger.error("Log channel ID not found in configuration."); - return; - } + 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; + } - 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 4b813c00c..9df21f6f8 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", - }); - } - - 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}`); + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "guildDelete", + }); } - 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(); + 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 logChannelId = this.client.config.logChannelId; - if (!logChannelId) { - this.client.logger.error("Log channel ID not found in configuration."); - return; - } + 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; + } - 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 6f7c8ab7b..800f563ac 100644 --- a/src/events/client/InteractionCreate.ts +++ b/src/events/client/InteractionCreate.ts @@ -1,249 +1,258 @@ 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", - }); - } + 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); + 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); - if (setup && interaction.channelId === setup.textId && !(commandInSetup && allowedCategories.includes(commandInSetup.category))) { - return await interaction.reply({ - content: T(locale, "event.interaction.setup_channel"), - ephemeral: true, - }); - } + 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 { commandName } = interaction; - await this.client.db.get(interaction.guildId); + const { commandName } = interaction; + await this.client.db.get(interaction.guildId); - const command = this.client.commands.get(commandName); - if (!command) return; + const command = this.client.commands.get(commandName); + if (!command) return; - 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 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; - 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 ( + !( + 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 logs = this.client.channels.cache.get(this.client.config.commandLogs); + const logs = this.client.channels.cache.get(this.client.config.commandLogs); - if (command.permissions) { - if (command.permissions?.client) { - const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); + if (command.permissions) { + if (command.permissions?.client) { + const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); - if (missingClientPermissions.length > 0) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_permission", { - permissions: missingClientPermissions.map((perm) => `\`${perm}\``).join(", "), - }), - ephemeral: true, - }); - } - } + 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?.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 (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 (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?.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), + ); - 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 }), - }); - } + 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.Connect)) { - return await interaction.reply({ - content: T(locale, "event.interaction.no_connect_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 (!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.Speak)) { + return await interaction.reply({ + content: T(locale, "event.interaction.no_speak_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 ( + (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.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 ( + 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.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 (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 (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.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"), - }); + 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 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 (!this.client.cooldown.has(commandName)) { + this.client.cooldown.set(commandName, new Collection()); } - } - } - } - if (!this.client.cooldown.has(commandName)) { - this.client.cooldown.set(commandName, new Collection()); - } + const now = Date.now(); + const timestamps = this.client.cooldown.get(commandName)!; + const cooldownAmount = (command.cooldown || 5) * 1000; - const now = Date.now(); - const timestamps = this.client.cooldown.get(commandName)!; - const cooldownAmount = (command.cooldown || 5) * 1000; + 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); + } - 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); - } + 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.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(); + 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; - await (logs as TextChannel).send({ embeds: [embed] }); + try { + await command.autocomplete(interaction); + } catch (error) { + console.error(error); + } } - } 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 d66231f40..51fd82ffc 100644 --- a/src/events/client/MessageCreate.ts +++ b/src/events/client/MessageCreate.ts @@ -1,258 +1,260 @@ 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", - }); - } - - 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); + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "messageCreate", + }); } - 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; - } + public async run(message: Message): Promise { + if (message.author.bot) 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 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 [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 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 ctx = new Context(message, args); - ctx.setArgs(args); - ctx.guildLocale = locale; + 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 clientMember = message.guild.members.resolve(this.client.user); - if (!(message.inGuild() && message.channel.permissionsFor(clientMember)?.has(PermissionFlagsBits.ViewChannel))) 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; - 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 ctx = new Context(message, args); + ctx.setArgs(args); + ctx.guildLocale = locale; - if (command.permissions) { - if (command.permissions?.client) { - const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); + const clientMember = message.guild.members.resolve(this.client.user); + if (!(message.inGuild() && message.channel.permissionsFor(clientMember)?.has(PermissionFlagsBits.ViewChannel))) return; - if (missingClientPermissions.length > 0) { - return await message.reply({ - content: T(locale, "event.message.no_permission", { - permissions: missingClientPermissions.map((perm) => `\`${perm}\``).join(", "), - }), - }); + 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 (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.permissions) { + if (command.permissions?.client) { + const missingClientPermissions = command.permissions.client.filter((perm) => !clientMember.permissions.has(perm)); - if (command.permissions?.dev && this.client.config.owners) { - const isDev = this.client.config.owners.includes(message.author.id); - if (!isDev) return; - } - } + if (missingClientPermissions.length > 0) { + return await message.reply({ + content: T(locale, "event.message.no_permission", { + permissions: missingClientPermissions.map((perm) => `\`${perm}\``).join(", "), + }), + }); + } + } - 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?.user) { + if (!(message.member as GuildMember).permissions.has(command.permissions.user)) { + return await message.reply({ + content: T(locale, "event.message.no_user_permission"), + }); + } - return await message.reply({ - content: T(locale, "event.message.vote_message"), - components: [voteBtn], - }); - } - } + if (command.permissions?.dev && this.client.config.owners) { + const isDev = this.client.config.owners.includes(message.author.id); + if (!isDev) return; + } + } - 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 (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 (!clientMember.permissions.has(PermissionFlagsBits.Connect)) { - return await message.reply({ - content: T(locale, "event.message.no_connect_permission", { command: command.name }), - }); - } + return await message.reply({ + content: T(locale, "event.message.vote_message"), + components: [voteBtn], + }); + } + } - if (!clientMember.permissions.has(PermissionFlagsBits.Speak)) { - return await message.reply({ - content: T(locale, "event.message.no_speak_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 ( - (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.Connect)) { + return await message.reply({ + content: T(locale, "event.message.no_connect_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 (!clientMember.permissions.has(PermissionFlagsBits.Speak)) { + return await message.reply({ + content: T(locale, "event.message.no_speak_permission", { 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 ( + (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.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 (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.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"), + }); + } + + 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.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 (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 (!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 (!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 (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 (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 (args.includes("@everyone") || args.includes("@here")) { - return await message.reply({ - content: T(locale, "event.message.no_mention_everyone"), - }); - } + if (args.includes("@everyone") || args.includes("@here")) { + return await message.reply({ + content: T(locale, "event.message.no_mention_everyone"), + }); + } - 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(); + 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] }); + await (logs as TextChannel).send({ embeds: [embed] }); + } + } } - } } - } } /** diff --git a/src/events/client/Ready.ts b/src/events/client/Ready.ts index 696222e93..ac45ae9d1 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 4144cb9db..b59ba5ea2 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", - }); - } - - 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 */ + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "setupButtons", + }); } - 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" })); + public async run(interaction: any): Promise { + const locale = await this.client.db.getLanguage(interaction.guildId); - 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, - }), - iconURL: interaction.member.displayAvatarURL({}), - }), - ], - components: getButtons(player, this.client), - }); - break; + 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); } - 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, + 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, }), - 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; + 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; + 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 "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; + + 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); + } + 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; + } } - 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 37d658975..72acb39fb 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; + } + + 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(() => {}); - } + 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 1c95876b5..80c2029d2 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(); - } + 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); } - }, 5000); } - } } /** diff --git a/src/events/player/NodeConnect.ts b/src/events/player/NodeConnect.ts index 743292dde..4a186ce96 100644 --- a/src/events/player/NodeConnect.ts +++ b/src/events/player/NodeConnect.ts @@ -2,42 +2,44 @@ 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", - }); - } - - public async run(node: string): Promise { - this.client.logger.success(`Node ${node} is ready!`); + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "nodeConnect", + }); + } - let data = await this.client.db.get_247(); - if (!data) return; + public async run(node: string): Promise { + this.client.logger.success(`Node ${node} is ready!`); - if (!Array.isArray(data)) { - data = [data]; - } + let data = await this.client.db.get_247(); + if (!data) return; - 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}`); + if (!Array.isArray(data)) { + data = [data]; } - }, index * 1000); - }); - BotLog.send(this.client, `Node ${node} is ready!`, "success"); - } + 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"); + } } diff --git a/src/events/player/NodeDestroy.ts b/src/events/player/NodeDestroy.ts index e7e07dd9f..924f7c125 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 428ac71f7..fb8c92e2a 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 2b5f5ddfa..8f3888dba 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 e1ff82eb3..b4d6bd967 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 73810a906..9a5111c32 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 73f381670..202964ae5 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 f30072d50..ccd09a034 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", - }); - } - - 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; + constructor(client: Lavamusic, file: string) { + super(client, file, { + name: "trackEnd", + }); } - await dispatcher.play(); + public async run(_player: Player, track: Song, dispatcher: Dispatcher): Promise { + dispatcher.previous = dispatcher.current; + dispatcher.current = null; - if (dispatcher.autoplay) { - await dispatcher.Autoplay(track); - } + 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 (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 0eea4ea0d..89eced69a 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; - }, - }); - - 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 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 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, - }); + collector.on("collect", async (interaction) => { + if (!(await checkDj(client, interaction))) { + await interaction.reply({ + content: T(locale, "player.trackStart.need_dj_role"), + ephemeral: true, + }); + return; } - 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; + + 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; } - 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 807e4f56b..2fc907477 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 fe6da1a3d..dd455b10f 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}`); + 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); } - } 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 fef290106..bd84eb4ff 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 2604f6077..adf545818 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 affe1e5b0..e8487f547 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 1cf08afb6..2e2f5b990 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 3bfd1d10e..da14bb27b 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; + 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(); } - 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); + 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; - } - } 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; + 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; } - if (this.msg) { - this.msg = await this.msg.edit(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; } - 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; + public locale(key: string, ...args: any) { + return T(this.guildLocale, key, ...args); } - 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 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 aa44af7f8..a31b2c82c 100644 --- a/src/structures/Dispatcher.ts +++ b/src/structures/Dispatcher.ts @@ -4,296 +4,299 @@ 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; - - 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, + 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, + }; + } } 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[]; - - 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)); - } + 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[]; - get exists(): boolean { - return this.client.queue.has(this.guildId); - } - - get volume(): number { - return this.player.volume; - } + 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)); + } - 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(); + get exists(): boolean { + return this.client.queue.has(this.guildId); } - } - public pause(): void { - if (this.player) { - this.paused = !this.paused; - this.player.setPaused(this.paused); + get volume(): number { + return this.player.volume; } - } - public remove(index: number): void { - if (this.player && index <= this.queue.length) { - this.queue.splice(index, 1); + 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 previousTrack(): void { - if (this.player && this.previous) { - this.queue.unshift(this.previous); - this.player.stopTrack(); + public pause(): void { + if (this.player) { + this.paused = !this.paused; + this.player.setPaused(this.paused); + } } - } - 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 remove(index: number): void { + if (this.player && index <= this.queue.length) { + this.queue.splice(index, 1); + } } - } - 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 previousTrack(): void { + if (this.player && this.previous) { + this.queue.unshift(this.previous); + this.player.stopTrack(); + } } - } - public skip(skipto = 1): void { - if (this.player) { - if (skipto > this.queue.length) { + public destroy(): void { this.queue.length = 0; - } else { - this.queue.splice(0, skipto - 1); - } - this.repeat = this.repeat === 1 ? 0 : this.repeat; - this.player.stopTrack(); + 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 seek(time: number): void { - if (this.player) { - this.player.seekTo(time); + 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 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 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 setLoop(loop: "off" | "repeat" | "queue"): void { - this.loop = loop; - } + public seek(time: number): void { + if (this.player) { + this.player.seekTo(time); + } + } - public buildTrack(track: Song | Track, user: User): Song { - return new Song(track, user); - } + 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 async isPlaying(): Promise { - if (this.queue.length && !this.current && !this.player.paused) { - await this.play(); + public setLoop(loop: "off" | "repeat" | "queue"): void { + this.loop = loop; } - } - public async Autoplay(song: Song): Promise { - if (!song?.info) return; + public buildTrack(track: Song | Track, user: User): Song { + return new Song(track, user); + } - 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; + public async isPlaying(): Promise { + if (this.queue.length && !this.current && !this.player.paused) { + await this.play(); } - // 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(); + } + + 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; + } } - } - break; - } - case "deezer": { - const resolve = await node.rest.resolve(`${SearchEngine.Deezer}:${song.info.author}`); - this.addAutoplayTrack(resolve); - break; + } catch (_error) { + return this.destroy(); } - 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(); } + 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 d0c8a4e64..d5e8edcf3 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 f4da7377d..d9d286689 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 2fb2c5175..96a58dd27 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,193 +26,195 @@ 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(); + } - private async loadCommands(): Promise { - const commandsPath = path.join(__dirname, "../commands"); - const commandDirs = fs.readdirSync(commandsPath); + 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); + } + } + }); + } - for (const dir of commandDirs) { - const commandFiles = fs.readdirSync(path.join(commandsPath, dir)).filter((file) => file.endsWith(".js")); + private async loadCommands(): Promise { + const commandsPath = path.join(__dirname, "../commands"); + const commandDirs = fs.readdirSync(commandsPath); - for (const file of commandFiles) { - const cmdModule = await import(`../commands/${dir}/${file}`); - const command: Command = new cmdModule.default(this); - command.category = dir; + for (const dir of commandDirs) { + const commandFiles = fs.readdirSync(path.join(commandsPath, dir)).filter((file) => file.endsWith(".js")); - this.commands.set(command.name, command); - command.aliases.forEach((alias: string) => { - this.aliases.set(alias, command.name); - }); + for (const file of commandFiles) { + const cmdModule = await import(`../commands/${dir}/${file}`); + const command: Command = new cmdModule.default(this); + command.category = dir; - 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, - }; - subOption.description_localizations = { - ...subOption.description_localizations, - [language2]: description, - }; - } - subOption.description = T(Locale.EnglishUS, subOption.description); + this.commands.set(command.name, command); + command.aliases.forEach((alias: string) => { + this.aliases.set(alias, command.name); }); - } - }); - } - this.body.push(data); + + 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, + }; + 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 ?? ""); + 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); + } + } - 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 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 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)); + + 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 9872cf336..b097b9cf9 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", + 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", + }, }, - 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 5f1dbcb08..5223677b3 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); + this.set(guild.id, dispatcher); + this.client.shoukaku.emit("playerCreate" as any, dispatcher.player); + } + return dispatcher; } - 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 c4c48f381..e74c4bd2e 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 31af364ae..47fb2b9fe 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 74dc3f1ff..612d7db77 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 b1febb7a7..444e44628 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: "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, - }, - ]; + 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 fc80e1cf4..452d2d0d4 100644 --- a/src/utils/SetupSystem.ts +++ b/src/utils/SetupSystem.ts @@ -6,338 +6,340 @@ 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); - try { - if (data) - m = await message.channel.messages.fetch({ - message: data.messageId, - cache: true, - }); - } catch (error) { - client.logger.error(error); - } - if (m) { + 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 (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; + 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; + } + } } - 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); } - } - } 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; - - 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); + const icon = player.current ? player.current.info.artworkUrl : client.config.links.img; + let m: Message; - 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 textChannel.messages.fetch({ - message: setup.messageId, - cache: true, - }); + m = await channel.messages.fetch({ message: msgId, 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 embed = client + 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, + 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(() => {}); + .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 { - 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(() => {}); + 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(() => {}); + } } - } } 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(() => {}); - } - setTimeout(async () => { - if (int && !int.ephemeral) { - await m.delete().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(() => {}); } - }, 2000); + setTimeout(async () => { + if (int && !int.ephemeral) { + await m.delete().catch(() => {}); + } + }, 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 109a8833e..eb00e3140 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); + 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; } - return fade; - } + /** + * 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; - /** - * 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; + 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); + } - 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); + return fade; } - return fade; - } + /** + * 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; - /** - * 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; + 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); + } + } - 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); - } + return fade; } - return fade; - } + /** + * 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; - /** - * 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; + 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); + } + } - 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; } - - return fade; - } } diff --git a/src/utils/Utils.ts b/src/utils/Utils.ts index 6c64eb1b2..6b59296ce 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 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 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 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 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, + }); + } } - 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 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; } - 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 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]}`; } - 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, - }); + public static formatNumber(number: number): string { + return number.toString().replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,"); + } - 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; + 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; } - await interaction.editReply(getButton(page)); - } else { - await interaction.reply({ - content: ctx.locale("buttons.errors.not_author"), - ephemeral: true, + 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; + } + + 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, }); - } - }); - collector.on("end", async () => { - await msg.edit({ embeds: [embed[page]], components: [] }); - }); - } + 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: [] }); + }); + } } /** diff --git a/tsconfig.json b/tsconfig.json index d3cbf1fd6..3e59d6116 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,21 @@ { - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "lib": ["esnext"], - "declaration": true, - "sourceMap": true, - "newLine": "crlf", - "outDir": "dist", - "rootDir": "src", - "strict": false, - "moduleResolution": "node", - "esModuleInterop": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["src/"], - "exclude": ["dist/", "node_modules/"] + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "lib": ["esnext"], + "declaration": true, + "sourceMap": true, + "newLine": "crlf", + "outDir": "dist", + "rootDir": "src", + "strict": false, + "moduleResolution": "node", + "esModuleInterop": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/"], + "exclude": ["dist/", "node_modules/"] } From a6d43d4e02ee0ff46d7b9f9c9868d79c4c80ddb8 Mon Sep 17 00:00:00 2001 From: hwangsihu Date: Thu, 12 Sep 2024 23:59:11 +0900 Subject: [PATCH 4/4] Format --- biome.json | 138 +++--- package.json | 110 ++--- process.json | 16 +- scripts/clean.js | 16 +- scripts/restart.ts | 18 +- src/LavaClient.ts | 4 +- src/commands/config/247.ts | 126 +++--- src/commands/config/Dj.ts | 338 +++++++------- src/commands/config/Language.ts | 246 +++++----- src/commands/config/Prefix.ts | 196 ++++---- src/commands/config/Setup.ts | 328 +++++++------- src/commands/dev/CreateInvite.ts | 112 +++-- src/commands/dev/DeleteInvites.ts | 78 ++-- src/commands/dev/Deploy.ts | 176 +++---- src/commands/dev/Eval.ts | 130 +++--- src/commands/dev/GuildLeave.ts | 124 ++--- src/commands/dev/GuildList.ts | 82 ++-- src/commands/dev/Restart.ts | 126 +++--- src/commands/filters/8d.ts | 108 ++--- src/commands/filters/BassBoost.ts | 118 ++--- src/commands/filters/Distorsion.ts | 126 +++--- src/commands/filters/Karaoke.ts | 118 ++--- src/commands/filters/LowPass.ts | 108 ++--- src/commands/filters/NightCore.ts | 108 ++--- src/commands/filters/Pitch.ts | 126 +++--- src/commands/filters/Rate.ts | 126 +++--- src/commands/filters/Reset.ts | 82 ++-- src/commands/filters/Rotation.ts | 106 ++--- src/commands/filters/Speed.ts | 126 +++--- src/commands/filters/Tremolo.ts | 108 ++--- src/commands/filters/Vibrato.ts | 108 ++--- src/commands/info/About.ts | 152 +++---- src/commands/info/Botinfo.ts | 138 +++--- src/commands/info/Help.ts | 201 ++++---- src/commands/info/Invite.ts | 88 ++-- src/commands/info/LavaLink.ts | 148 +++--- src/commands/info/Ping.ts | 124 ++--- src/commands/music/Autoplay.ts | 100 ++-- src/commands/music/ClearQueue.ts | 92 ++-- src/commands/music/Grab.ts | 128 +++--- src/commands/music/Join.ts | 132 +++--- src/commands/music/Leave.ts | 82 ++-- src/commands/music/Loop.ts | 100 ++-- src/commands/music/Nowplaying.ts | 112 ++--- src/commands/music/Pause.ts | 82 ++-- src/commands/music/Play.ts | 340 +++++++------- src/commands/music/PlayNext.ts | 330 +++++++------- src/commands/music/Queue.ts | 156 ++++--- src/commands/music/Remove.ts | 116 ++--- src/commands/music/Replay.ts | 82 ++-- src/commands/music/Resume.ts | 82 ++-- src/commands/music/Search.ts | 220 ++++----- src/commands/music/Seek.ts | 142 +++--- src/commands/music/Shuffle.ts | 80 ++-- src/commands/music/Skip.ts | 102 ++--- src/commands/music/Skipto.ts | 110 ++--- src/commands/music/Stop.ts | 74 +-- src/commands/music/Volume.ts | 120 ++--- src/commands/playlist/AddSong.ts | 264 +++++------ src/commands/playlist/Create.ts | 124 ++--- src/commands/playlist/Delete.ts | 144 +++--- src/commands/playlist/List.ts | 224 ++++----- src/commands/playlist/Load.ts | 198 ++++---- src/commands/playlist/RemoveSong.ts | 216 ++++----- src/commands/playlist/Steal.ts | 356 +++++++-------- src/config.ts | 138 +++--- src/database/server.ts | 412 ++++++++--------- src/events/client/ChannelDelete.ts | 61 ++- src/events/client/GuildCreate.ts | 122 ++--- src/events/client/GuildDelete.ts | 122 ++--- src/events/client/InteractionCreate.ts | 433 +++++++++--------- src/events/client/MessageCreate.ts | 438 +++++++++--------- src/events/client/Ready.ts | 48 +- src/events/client/SetupButtons.ts | 434 +++++++++--------- src/events/client/SetupSystem.ts | 98 ++-- src/events/client/VoiceStateUpdate.ts | 120 ++--- src/events/player/NodeConnect.ts | 68 ++- src/events/player/NodeDestroy.ts | 34 +- src/events/player/NodeDisconnect.ts | 20 +- src/events/player/NodeError.ts | 22 +- src/events/player/NodeRaw.ts | 18 +- src/events/player/NodeReconnect.ts | 20 +- src/events/player/QueueEnd.ts | 58 +-- src/events/player/TrackEnd.ts | 52 +-- src/events/player/TrackStart.ts | 434 +++++++++--------- src/index.ts | 56 +-- src/plugin/index.ts | 32 +- src/plugin/plugins/antiCrash.ts | 44 +- src/plugin/plugins/keepAlive.ts | 28 +- src/plugin/plugins/updateStatus.ts | 12 +- src/structures/Command.ts | 138 +++--- src/structures/Context.ts | 224 ++++----- src/structures/Dispatcher.ts | 497 ++++++++++---------- src/structures/Event.ts | 34 +- src/structures/I18n.ts | 52 +-- src/structures/Lavamusic.ts | 370 ++++++++------- src/structures/Logger.ts | 96 ++-- src/structures/Queue.ts | 126 +++--- src/structures/Shoukaku.ts | 68 +-- src/types.ts | 140 +++--- src/utils/BotLog.ts | 28 +- src/utils/Buttons.ts | 130 +++--- src/utils/SetupSystem.ts | 604 ++++++++++++------------- src/utils/ThemeSelector.ts | 122 ++--- src/utils/Utils.ts | 298 ++++++------ tsconfig.json | 38 +- 106 files changed, 7612 insertions(+), 7668 deletions(-) diff --git a/biome.json b/biome.json index fc1aafd72..86ea89a20 100644 --- a/biome.json +++ b/biome.json @@ -1,74 +1,74 @@ { - "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", - "organizeImports": { - "enabled": true - }, - "linter": { - "enabled": true, - "rules": { - "all": true, - "suspicious": { - "noConfusingVoidType": "off", - "noConsoleLog": "off", - "noEmptyBlockStatements": "off", - "noExplicitAny": "off", - "noGlobalIsFinite": "off", - "noGlobalIsNan": "off", - "useAwait": "off" - }, - "style": { - "noDefaultExport": "off", - "noInferrableTypes": "off", - "noNamespaceImport": "off", - "noNonNullAssertion": "off", - "noParameterAssign": "off", - "useBlockStatements": "off", - "useFilenamingConvention": "off", - "useNamingConvention": "off", - "useNumberNamespace": "off", - "useSingleCaseStatement": "off" - }, - "complexity": { - "noBannedTypes": "off", - "noForEach": "off", - "noStaticOnlyClass": "off", - "noExcessiveCognitiveComplexity": { - "level": "warn", - "options": { - "maxAllowedComplexity": 255 - } - } - }, - "security": { - "noGlobalEval": "off" - }, - "correctness": { - "noNodejsModules": "off", - "noVoidTypeReturn": "off" - }, - "performance": { - "noBarrelFile": "off" - } + "$schema": "https://biomejs.dev/schemas/1.8.3/schema.json", + "organizeImports": { + "enabled": true + }, + "linter": { + "enabled": true, + "rules": { + "all": true, + "suspicious": { + "noConfusingVoidType": "off", + "noConsoleLog": "off", + "noEmptyBlockStatements": "off", + "noExplicitAny": "off", + "noGlobalIsFinite": "off", + "noGlobalIsNan": "off", + "useAwait": "off" + }, + "style": { + "noDefaultExport": "off", + "noInferrableTypes": "off", + "noNamespaceImport": "off", + "noNonNullAssertion": "off", + "noParameterAssign": "off", + "useBlockStatements": "off", + "useFilenamingConvention": "off", + "useNamingConvention": "off", + "useNumberNamespace": "off", + "useSingleCaseStatement": "off" + }, + "complexity": { + "noBannedTypes": "off", + "noForEach": "off", + "noStaticOnlyClass": "off", + "noExcessiveCognitiveComplexity": { + "level": "warn", + "options": { + "maxAllowedComplexity": 255 + } } - }, + }, + "security": { + "noGlobalEval": "off" + }, + "correctness": { + "noNodejsModules": "off", + "noVoidTypeReturn": "off" + }, + "performance": { + "noBarrelFile": "off" + } + } + }, + "formatter": { + "enabled": true, + "indentWidth": 2, + "indentStyle": "space", + "lineEnding": "crlf", + "lineWidth": 140, + "formatWithErrors": true + }, + "javascript": { "formatter": { - "enabled": true, - "indentWidth": 4, - "indentStyle": "space", - "lineEnding": "crlf", - "lineWidth": 140, - "formatWithErrors": true - }, - "javascript": { - "formatter": { - "quoteStyle": "double", - "arrowParentheses": "always", - "bracketSameLine": true, - "semicolons": "always" - } - }, - "files": { - "ignoreUnknown": false, - "ignore": [".vscode", "dist", "locales", "node_modules"] + "quoteStyle": "double", + "arrowParentheses": "always", + "bracketSameLine": true, + "semicolons": "always" } + }, + "files": { + "ignoreUnknown": false, + "ignore": [".vscode", "dist", "locales", "node_modules"] + } } diff --git a/package.json b/package.json index cfc04ee6e..9ba6624fa 100644 --- a/package.json +++ b/package.json @@ -1,57 +1,57 @@ { - "name": "lavamusic", - "version": "4.6.7", - "description": "LavaMusic is a music bot for Discord, written in JavaScript using the Discord.js, Typescript, Shoukaku (Lavalink) library.", - "main": "dist/index.js", - "type": "module", - "scripts": { - "start": "npm run clean && node .", - "db:push": "npx prisma db push", - "db:migrate": "npx prisma migrate dev --name init", - "build": "tsc --project tsconfig.json", - "clean": "node scripts/clean.js && npm run build", - "lint": "biome lint --write", - "format": "biome format --write" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/appujet/lavamusic.git" - }, - "keywords": ["discord", "music", "bot", "lavalink", "shoukaku", "lavamusic", "typescript", "prisma"], - "author": "appujet", - "license": "GPL-3.0", - "bugs": { - "url": "https://github.com/appujet/lavamusic/issues" - }, - "homepage": "https://github.com/appujet/lavamusic#readme", - "devDependencies": { - "@biomejs/biome": "^1.8.3", - "@types/i18n": "^0.13.12", - "@types/node": "^22.5.4", - "@types/signale": "^1.4.7", - "prisma": "^5.19.1", - "typescript": "^5.6.2" - }, - "dependencies": { - "@prisma/client": "^5.19.1", - "@top-gg/sdk": "^3.1.6", - "discord.js": "^14.16.1", - "dotenv": "^16.4.5", - "i18n": "^0.15.1", - "node-system-stats": "^1.3.0", - "shoukaku": "^4.1.1", - "signale": "^1.4.0", - "topgg-autoposter": "^2.0.2", - "tslib": "^2.7.0", - "undici": "^6.19.8" - }, - "signale": { - "displayScope": true, - "displayBadge": true, - "displayDate": true, - "displayFilename": true, - "displayLabel": true, - "displayTimestamp": true, - "underlineLabel": true - } + "name": "lavamusic", + "version": "4.6.7", + "description": "LavaMusic is a music bot for Discord, written in JavaScript using the Discord.js, Typescript, Shoukaku (Lavalink) library.", + "main": "dist/index.js", + "type": "module", + "scripts": { + "start": "npm run clean && node .", + "db:push": "npx prisma db push", + "db:migrate": "npx prisma migrate dev --name init", + "build": "tsc --project tsconfig.json", + "clean": "node scripts/clean.js && npm run build", + "lint": "biome lint --write", + "format": "biome format --write" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/appujet/lavamusic.git" + }, + "keywords": ["discord", "music", "bot", "lavalink", "shoukaku", "lavamusic", "typescript", "prisma"], + "author": "appujet", + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/appujet/lavamusic/issues" + }, + "homepage": "https://github.com/appujet/lavamusic#readme", + "devDependencies": { + "@biomejs/biome": "^1.8.3", + "@types/i18n": "^0.13.12", + "@types/node": "^22.5.4", + "@types/signale": "^1.4.7", + "prisma": "^5.19.1", + "typescript": "^5.6.2" + }, + "dependencies": { + "@prisma/client": "^5.19.1", + "@top-gg/sdk": "^3.1.6", + "discord.js": "^14.16.1", + "dotenv": "^16.4.5", + "i18n": "^0.15.1", + "node-system-stats": "^1.3.0", + "shoukaku": "^4.1.1", + "signale": "^1.4.0", + "topgg-autoposter": "^2.0.2", + "tslib": "^2.7.0", + "undici": "^6.19.8" + }, + "signale": { + "displayScope": true, + "displayBadge": true, + "displayDate": true, + "displayFilename": true, + "displayLabel": true, + "displayTimestamp": true, + "underlineLabel": true + } } diff --git a/process.json b/process.json index 7f2115ba3..bda8eaceb 100644 --- a/process.json +++ b/process.json @@ -1,10 +1,10 @@ { - "apps": [ - { - "name": "lavamusic", - "script": "dist/index.js", - "node_args": ["--enable-source-maps"], - "restart_delay": 10000 - } - ] + "apps": [ + { + "name": "lavamusic", + "script": "dist/index.js", + "node_args": ["--enable-source-maps"], + "restart_delay": 10000 + } + ] } 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 c7528a8ec..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: "⏩", - rewind: "⏪", - 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 642656fb7..6f6df052f 100644 --- a/src/database/server.ts +++ b/src/database/server.ts @@ -1,212 +1,212 @@ -import { type Dj, type Guild, type Playlist, PrismaClient, type Role, type Song, type Setup, type Stay } from "@prisma/client"; +import { type Dj, type Guild, type Playlist, PrismaClient, type Role, type Setup, type Song, type Stay } from "@prisma/client"; 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 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(); - } + 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 444e44628..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: "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, - }, - ]; + 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 3e59d6116..d3cbf1fd6 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,21 +1,21 @@ { - "compilerOptions": { - "target": "esnext", - "module": "esnext", - "lib": ["esnext"], - "declaration": true, - "sourceMap": true, - "newLine": "crlf", - "outDir": "dist", - "rootDir": "src", - "strict": false, - "moduleResolution": "node", - "esModuleInterop": true, - "experimentalDecorators": true, - "emitDecoratorMetadata": true, - "skipLibCheck": true, - "forceConsistentCasingInFileNames": true - }, - "include": ["src/"], - "exclude": ["dist/", "node_modules/"] + "compilerOptions": { + "target": "esnext", + "module": "esnext", + "lib": ["esnext"], + "declaration": true, + "sourceMap": true, + "newLine": "crlf", + "outDir": "dist", + "rootDir": "src", + "strict": false, + "moduleResolution": "node", + "esModuleInterop": true, + "experimentalDecorators": true, + "emitDecoratorMetadata": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src/"], + "exclude": ["dist/", "node_modules/"] }