diff --git a/src/discord/MusicPlayer/Join.ts b/src/discord/MusicPlayer/Join.ts index 62ee037..c0e384d 100644 --- a/src/discord/MusicPlayer/Join.ts +++ b/src/discord/MusicPlayer/Join.ts @@ -1,7 +1,7 @@ import DiscordModule, { HybridInteractionMessage } from "../../utils/DiscordModule"; -import { Message, CommandInteraction, Interaction, VoiceChannel, Permissions, GuildMember, DMChannel, StageChannel, MessageActionRow, MessageButton, TextChannel } from "discord.js"; -import { makeSuccessEmbed, makeErrorEmbed, sendMessage, sendMessageOrInteractionResponse, sendHybridInteractionMessageResponse, makeInfoEmbed } from "../../utils/DiscordMessage"; +import { Message, CommandInteraction, Interaction, VoiceChannel, Permissions, GuildMember, DMChannel, StageChannel, MessageActionRow, MessageButton, TextChannel, VoiceBasedChannel } from "discord.js"; +import { makeSuccessEmbed, makeErrorEmbed, sendMessage, sendHybridInteractionMessageResponse, makeInfoEmbed } from "../../utils/DiscordMessage"; import DiscordProvider from "../../providers/Discord"; import DiscordMusicPlayer, { PlayerPlayingEvent, PlayerErrorEvent, VoiceDisconnectedEvent, ValidTracks, DiscordMusicPlayerInstance, DiscordMusicPlayerLoopMode } from "../../providers/DiscordMusicPlayer"; @@ -85,48 +85,52 @@ const EMBEDS = { } } -export async function joinVoiceChannelProcedure (data: Interaction | Message, instance: (DiscordMusicPlayerInstance | null), voiceChannel: (VoiceChannel | StageChannel)) { +export async function joinVoiceChannelProcedure (data: HybridInteractionMessage, instance: (DiscordMusicPlayerInstance | null), voiceChannel: (VoiceChannel | StageChannel)) { - const isSlashCommand = data instanceof CommandInteraction && data.isCommand(); - const isAcceptableInteraction = data instanceof Interaction && (data.isSelectMenu() || data.isButton()); - const isMessage = data instanceof Message; + const isSlashCommand = data.isSlashCommand(); + const isAcceptableInteraction = data.isSelectMenu() || data.isButton(); + const isMessage = data.isMessage(); if ((!isSlashCommand && !isAcceptableInteraction) && !isMessage) return; - if (!data.member) return; - if (!data.channel) return; - if (!data.guildId) return; + const member = data.getMember(); + const channel = data.getChannel(); + const guild = data.getGuild(); - if (data.channel instanceof DMChannel) return; - if (!(data.channel instanceof TextChannel)) return; + if(!member || !channel || !guild) return; - const channel: any = isMessage ? data.member.voice.channel : DiscordProvider.client.guilds.cache.get((data as Interaction).guildId!)!.members.cache.get((data as Interaction).user.id)?.voice.channel; - if (!channel) return; + if (channel instanceof DMChannel) return; + if (!(channel instanceof TextChannel)) return; + const memberVoiceChannel = member.voice.channel;//isMessage ? member.voice.channel : DiscordProvider.client.guilds.cache.get(guild.id)!.members.cache.get((data as Interaction).user.id)?.voice.channel; + if (!memberVoiceChannel) return; + + const bot = guild.me; + if(!bot) return; // If already in VoiceChannel - if (DiscordProvider.client.guilds.cache.get(data.guildId)!.me!.voice.channelId) { + if (bot.voice.channelId) { // But, no music instance yet (The bot might just restarted) if (!instance) { // User is in different VoiceChannel - if (channel.id !== DiscordProvider.client.guilds.cache.get(data.guildId)?.me?.voice) { + if (memberVoiceChannel.id !== bot.voice.channelId) { //Disconnect it - await DiscordProvider.client.guilds.cache.get(data.guildId)?.me?.voice.disconnect(); + await bot.voice.disconnect(); } //Create instance for a new one - DiscordMusicPlayer.createGuildInstance(data.guildId, voiceChannel); - instance = DiscordMusicPlayer.getGuildInstance(data.guildId); + DiscordMusicPlayer.createGuildInstance(guild.id, voiceChannel); + instance = DiscordMusicPlayer.getGuildInstance(guild.id); - instance!.joinVoiceChannel(voiceChannel, data.channel); + instance!.joinVoiceChannel(voiceChannel, channel); if(!isAcceptableInteraction) - await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.VOICECHANNEL_JOINED(data)] }); + await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.VOICECHANNEL_JOINED(data.getRaw())] }); } // And, already have instance on the guild else { // And, User VoiceChannel is same as the instance if (channel.id === instance.voiceChannel.id) { if(!isAcceptableInteraction) - return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.VOICECHANNEL_ALREADY_JOINED(data)] }); + return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.VOICECHANNEL_ALREADY_JOINED(data.getRaw())] }); else return; } // But, not the same VoiceChannel @@ -135,15 +139,15 @@ export async function joinVoiceChannelProcedure (data: Interaction | Message, in // And someone else is using the bot if(activeMembers.size > 0) { if(!isAcceptableInteraction) - return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.VOICECHANNEL_INUSE(data)] }); + return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.VOICECHANNEL_INUSE(data.getRaw())] }); else return; } // And alone in the VoiceChannel else { // Move to the new voice channel - await DiscordProvider.client.guilds.cache.get(data.guildId)?.me?.voice.setChannel(voiceChannel); + await bot.voice.setChannel(voiceChannel); if(!isAcceptableInteraction) - return await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.VOICECHANNEL_JOINED(data)] }); + return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.VOICECHANNEL_JOINED(data.getRaw())] }); else return; } } @@ -154,14 +158,14 @@ export async function joinVoiceChannelProcedure (data: Interaction | Message, in else { if (instance) - await DiscordMusicPlayer.destoryGuildInstance(data.guildId!); + await DiscordMusicPlayer.destoryGuildInstance(guild.id); - DiscordMusicPlayer.createGuildInstance(data.guildId, voiceChannel); - instance = DiscordMusicPlayer.getGuildInstance(data.guildId); + DiscordMusicPlayer.createGuildInstance(guild.id, voiceChannel); + instance = DiscordMusicPlayer.getGuildInstance(guild.id); - instance!.joinVoiceChannel(voiceChannel, data.channel); + instance!.joinVoiceChannel(voiceChannel, channel); if(!isAcceptableInteraction) - await sendMessageOrInteractionResponse(data, { embeds: [EMBEDS.VOICECHANNEL_JOINED(data)] }); + await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.VOICECHANNEL_JOINED(data.getRaw())] }); } if (!instance) return; @@ -191,23 +195,23 @@ export async function joinVoiceChannelProcedure (data: Interaction | Message, in if (event.instance.textChannel) { if(event.instance.getLoopMode() === DiscordMusicPlayerLoopMode.Current) { isLoopMessageSent = true; - await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.NOW_REPEATING(data, event.instance.queue.track[0])], components: [row] }); + await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.NOW_REPEATING(data.getRaw(), event.instance.queue.track[0])], components: [row] }); } else { - await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.NOW_PLAYING(data, event.instance.queue.track[0])], components: [row] }); + await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.NOW_PLAYING(data.getRaw(), event.instance.queue.track[0])], components: [row] }); } } }); instance.events.on('error', async (event: PlayerErrorEvent) => { if (event.instance.textChannel) { - await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.MUSIC_ERROR(data, event.error)] }); + await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.MUSIC_ERROR(data.getRaw(), event.error)] }); } }); instance.events.on('disconnect', async (event: VoiceDisconnectedEvent) => { if (event.instance.textChannel) { - await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.VOICECHANNEL_DISCONNECTED(data)] }); + await sendMessage(event.instance.textChannel, undefined, { embeds: [EMBEDS.VOICECHANNEL_DISCONNECTED(data.getRaw())] }); } DiscordMusicPlayer.destoryGuildInstance(event.instance.voiceChannel.guildId); @@ -241,6 +245,7 @@ export default class Join extends DiscordModule { return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.USER_NOT_IN_VOICECHANNEL(data.getRaw())] }); const instance = DiscordMusicPlayer.getGuildInstance(guild.id); - await joinVoiceChannelProcedure(data.getRaw(), instance, voiceChannel); + console.log(data.isButton) + await joinVoiceChannelProcedure(data, instance, voiceChannel); } } \ No newline at end of file diff --git a/src/discord/MusicPlayer/Play.ts b/src/discord/MusicPlayer/Play.ts index 0a3e7a0..d433b70 100644 --- a/src/discord/MusicPlayer/Play.ts +++ b/src/discord/MusicPlayer/Play.ts @@ -142,7 +142,7 @@ export default class Play extends DiscordModule { return await sendHybridInteractionMessageResponse(hybridData, { embeds: [EMBEDS.USER_NOT_IN_VOICECHANNEL(hybridData.getRaw())] }, true); if (!DiscordMusicPlayer.isGuildInstanceExists(guild.id)) - await joinVoiceChannelProcedure(interaction, null, voiceChannel); + await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction) , null, voiceChannel); let instance = DiscordMusicPlayer.getGuildInstance(guild.id); @@ -150,7 +150,7 @@ export default class Play extends DiscordModule { return await sendHybridInteractionMessageResponse(hybridData, { embeds: [EMBEDS.USER_NOT_IN_SAME_VOICECHANNEL(hybridData.getRaw())] }, true); if (!instance!.isConnected()) { - await joinVoiceChannelProcedure(interaction, instance!, voiceChannel); + await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction), instance!, voiceChannel); instance = DiscordMusicPlayer.getGuildInstance(guild.id); } @@ -206,7 +206,7 @@ export default class Play extends DiscordModule { return await sendHybridInteractionMessageResponse(hybridData, { embeds: [EMBEDS.USER_NOT_IN_VOICECHANNEL(interaction)] }, true); if (!DiscordMusicPlayer.isGuildInstanceExists(guild.id)) - await joinVoiceChannelProcedure(interaction, null, voiceChannel); + await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction), null, voiceChannel); let instance = DiscordMusicPlayer.getGuildInstance(guild.id); @@ -215,7 +215,7 @@ export default class Play extends DiscordModule { return await sendHybridInteractionMessageResponse(hybridData, { embeds: [EMBEDS.USER_NOT_IN_SAME_VOICECHANNEL(interaction)] }, true); if (!instance!.isConnected()) { - await joinVoiceChannelProcedure(interaction, instance!, voiceChannel); + await joinVoiceChannelProcedure(new HybridInteractionMessage(interaction), instance!, voiceChannel); instance = DiscordMusicPlayer.getGuildInstance(guild.id); } @@ -258,7 +258,7 @@ export default class Play extends DiscordModule { const voiceChannel = member.voice.channel; if (!DiscordMusicPlayer.isGuildInstanceExists(guild.id)) { - await joinVoiceChannelProcedure(data.getRaw(), null, voiceChannel); + await joinVoiceChannelProcedure(data, null, voiceChannel); } let instance = DiscordMusicPlayer.getGuildInstance(guild.id); @@ -267,7 +267,7 @@ export default class Play extends DiscordModule { return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.USER_NOT_IN_SAME_VOICECHANNEL(data.getRaw())] }, true); if (!instance!.isConnected()) { - await joinVoiceChannelProcedure(data.getRaw(), instance!, voiceChannel); + await joinVoiceChannelProcedure(data, instance!, voiceChannel); instance = DiscordMusicPlayer.getGuildInstance(guild.id); } diff --git a/src/discord/MusicPlayer/Search.ts b/src/discord/MusicPlayer/Search.ts index 5a0df9b..7fc12b6 100644 --- a/src/discord/MusicPlayer/Search.ts +++ b/src/discord/MusicPlayer/Search.ts @@ -123,7 +123,7 @@ export default class Search extends DiscordModule { if (!DiscordMusicPlayer.isGuildInstanceExists(guild.id)) - await joinVoiceChannelProcedure(data.getRaw(), null, voiceChannel); + await joinVoiceChannelProcedure(data, null, voiceChannel); let instance = DiscordMusicPlayer.getGuildInstance(guild.id); if (!instance) return; @@ -132,7 +132,7 @@ export default class Search extends DiscordModule { return await sendHybridInteractionMessageResponse(data, { embeds: [EMBEDS.USER_NOT_IN_SAME_VOICECHANNEL(data.getRaw())] }); if (!instance.isConnected()) { - await joinVoiceChannelProcedure(data.getRaw(), instance!, voiceChannel); + await joinVoiceChannelProcedure(data, instance!, voiceChannel); instance = DiscordMusicPlayer.getGuildInstance(guild.id); } diff --git a/src/utils/DiscordMessage.ts b/src/utils/DiscordMessage.ts index cbd6eda..cd8d36c 100644 --- a/src/utils/DiscordMessage.ts +++ b/src/utils/DiscordMessage.ts @@ -23,107 +23,104 @@ const emotes = { yumiloading: '' }; -export function makeEmbed( - icon: string | undefined, - title: string, - description: any, - color: ColorResolvable, - fields: any, - user: User, - setTimestamp: boolean -) { +interface EmbedData { + icon?: string; + title: string; + description?: any; + color?: ColorResolvable; + fields?: any; + user?: User; + setTimestamp: boolean; +} + +export function makeEmbed(data: EmbedData) { const embed = new MessageEmbed(); - embed.setColor(color || '#FFFFFF'); + embed.setColor(data.color || '#FFFFFF'); - if (typeof icon === 'undefined') embed.setTitle(title); - else embed.setTitle(`${icon} ${title}`); + if (!data.icon) embed.setTitle(data.title); + else embed.setTitle(`${data.icon} ${data.title}`); - if (typeof description !== 'undefined') embed.setDescription(description); + if (data.description) embed.setDescription(data.description); - if (setTimestamp) embed.setTimestamp(); + if (data.setTimestamp) embed.setTimestamp(); - if (typeof user !== 'undefined') + if (data.user) embed.footer = { - text: `${user.username} | v${App.version}`, - iconURL: `${user.displayAvatarURL()}?size=4096` + text: `${data.user.username} | v${App.version}`, + iconURL: `${data.user.displayAvatarURL()}?size=4096` }; else embed.footer = { text: `v${App.version}` }; - if (typeof fields !== 'undefined') embed.addFields(fields); + if (data.fields) embed.addFields(data.fields); return embed; } +export function makeInfoEmbed(options: any) { + return makeEmbed({ + icon: !options.icon ? '🔮' : options.icon, + title: options.title, + description: options.description, + color: '#C7CEEA', + fields: options.fields, + user: options.user, + setTimestamp: options.setTimestamp || true + }); +} + export function makeSuccessEmbed(options: any) { - return makeEmbed( - typeof options.icon === 'undefined' ? '✅' : options.icon, - options.title, - options.description, - '#B5EAD7', - options.fields, - options.user, - options.setTimestamp || true - ); + return makeEmbed({ + icon: !options.icon ? '✅' : options.icon, + title: options.title, + description: options.description, + color: '#B5EAD7', + fields: options.fields, + user: options.user, + setTimestamp: options.setTimestamp || true + }); } export function makeWarningEmbed(options: any) { - return makeEmbed( - typeof options.icon === 'undefined' ? '⚠️' : options.icon, - options.title, - options.description, - '#FFEEAD', - options.fields, - options.user, - options.setTimestamp || true - ); + return makeEmbed({ + icon: !options.icon ? '⚠️' : options.icon, + title: options.title, + description: options.description, + color: '#FFEEAD', + fields: options.fields, + user: options.user, + setTimestamp: options.setTimestamp || true + }); } export function makeErrorEmbed(options: any) { - return makeEmbed( - typeof options.icon === 'undefined' ? '❌' : options.icon, - options.title, - options.description, - '#FF9AA2', - options.fields, - options.user, - options.setTimestamp || true - ); + return makeEmbed({ + icon: !options.icon ? '❌' : options.icon, + title: options.title, + description: options.description, + color: '#FF9AA2', + fields: options.fields, + user: options.user, + setTimestamp: options.setTimestamp || true + }); } export function makeProcessingEmbed(options: any) { - return makeEmbed( - typeof options.icon === 'undefined' ? getEmotes().yumiloading : options.icon, - options.title, - options.description, - '#E2F0CB', - options.fields, - options.user, - options.setTimestamp || true - ); -} - -export function makeInfoEmbed(options: any) { - return makeEmbed( - typeof options.icon === 'undefined' ? '🔮' : options.icon, - options.title, - options.description, - '#C7CEEA', - options.fields, - options.user, - options.setTimestamp || true - ); + return makeEmbed({ + icon: !options.icon ? getEmotes().yumiloading : options.icon, + title: options.title, + description: options.description, + color: '#E2F0CB', + fields: options.fields, + user: options.user, + setTimestamp: options.setTimestamp || true + }); } export async function sendMessage( - channel: - | TextChannel - | DMChannel - | BaseGuildTextChannel - | GuildTextBasedChannel - | PartialDMChannel, + channel: TextChannel | DMChannel | BaseGuildTextChannel | GuildTextBasedChannel | PartialDMChannel, user: User | undefined, options: string | MessagePayload | MessageOptions ) { @@ -150,10 +147,7 @@ export async function sendMessage( } } -export async function sendReply( - rMessage: Message, - options: string | MessagePayload | MessageOptions -) { +export async function sendReply(rMessage: Message, options: string | MessagePayload | MessageOptions) { let message; try { @@ -172,52 +166,6 @@ export async function sendReply( } } -export async function sendMessageOrInteractionResponse( - data: Message | Interaction, - payload: MessageOptions | InteractionReplyOptions, - replace = false -) { - const isSlashCommand = data instanceof CommandInteraction && data.isCommand(); - const isMessage = data instanceof Message; - - if ( - isSlashCommand || - (data instanceof Interaction && (data.isSelectMenu() || data.isButton())) - ) { - if (!data.replied) { - let message; - try { - if (!data.deferred) return await data.reply(payload as InteractionReplyOptions); - else return await data.editReply(payload); - } catch (errorDM) { - Logger.error( - `Cannot find available destinations to send the message CID: ${ - data.channel!.id - } UID: ${data.user.id} DM_ERR: ${errorDM}` - ); - return; - } finally { - return message; - } - } else { - let message; - try { - if (replace) return await data.editReply(payload); - else return await data.followUp(payload as InteractionReplyOptions); - } catch (errorDM) { - Logger.error( - `Cannot find available destinations to send the message CID: ${ - data.channel!.id - } UID: ${data.user.id} DM_ERR: ${errorDM}` - ); - return; - } finally { - return message; - } - } - } else if (isMessage) return await sendReply(data, payload as MessageOptions); -} - export async function sendHybridInteractionMessageResponse( data: HybridInteractionMessage, payload: MessageOptions | InteractionReplyOptions, @@ -238,9 +186,9 @@ export async function sendHybridInteractionMessageResponse( } } catch (errorDM) { Logger.error( - `Cannot find available destinations to send the message CID: ${ - messageComponent.channel!.id - } UID: ${messageComponent.user.id} DM_ERR: ${errorDM}` + `Cannot find available destinations to send the message CID: ${messageComponent.channel!.id} UID: ${ + messageComponent.user.id + } DM_ERR: ${errorDM}` ); return; } finally { @@ -250,23 +198,19 @@ export async function sendHybridInteractionMessageResponse( let message; try { if (replace) return (await messageComponent.editReply(payload)) as Message; - else - return (await messageComponent.followUp( - payload as InteractionReplyOptions - )) as Message; + else return (await messageComponent.followUp(payload as InteractionReplyOptions)) as Message; } catch (errorDM) { Logger.error( - `Cannot find available destinations to send the message CID: ${ - messageComponent.channel!.id - } UID: ${messageComponent.user.id} DM_ERR: ${errorDM}` + `Cannot find available destinations to send the message CID: ${messageComponent.channel!.id} UID: ${ + messageComponent.user.id + } DM_ERR: ${errorDM}` ); return; } finally { return message; } } - } else if (data.isMessage()) - return await sendReply(data.getMessage(), payload as MessageOptions); + } else if (data.isMessage()) return await sendReply(data.getMessage(), payload as MessageOptions); } export function getEmotes() {