206 lines
7.6 KiB
TypeScript
206 lines
7.6 KiB
TypeScript
import { Client, TextChannel, CommandInteraction, Guild, GuildChannel, TextBasedChannel, VoiceChannel, EmbedBuilder, ButtonBuilder, ActionRowBuilder, ButtonInteraction } from 'discord.js'
|
|
import { useMainPlayer, useQueue } from 'discord-player'
|
|
import { Document } from 'mongoose'
|
|
import getUptime from './getUptime'
|
|
|
|
type ChannelInferrable = {
|
|
channel: TextBasedChannel | VoiceChannel
|
|
guild?: Guild
|
|
}
|
|
|
|
export class PlayerMetadata {
|
|
public constructor(public data: ChannelInferrable) {
|
|
if (data.channel.isDMBased()) { throw new Error('PlayerMetadata cannot be created from a DM') }
|
|
if (!data.channel) { throw new Error('PlayerMetadata can only be created from a channel') }
|
|
}
|
|
public get channel() { return this.data.channel! }
|
|
public get guild() { return this.data.guild || (this.data.channel as GuildChannel).guild }
|
|
|
|
public static create(data: ChannelInferrable | CommandInteraction) {
|
|
if (data instanceof CommandInteraction) {
|
|
if (!data.inGuild()) { throw new Error('PlayerMetadata cannot be created from a DM') }
|
|
|
|
return new PlayerMetadata({ channel: data.channel!, guild: data.guild! })
|
|
}
|
|
return new PlayerMetadata(data);
|
|
}
|
|
}
|
|
|
|
export const bots = ['1065047326860783636', '1119343522059927684', '1119344050412204032', '1210714000321548329', '660961595006124052']
|
|
export const playerButtons = ['loop', 'pause', 'previous', 'resume', 'shuffle', 'skip', 'stop', 'volume_down', 'volume_up']
|
|
|
|
export async function playerDisco (client: Client, guildProfile: Document) {
|
|
try {
|
|
let guild = client.guilds.cache.get(guildProfile.get('guildId'))
|
|
if (!guild) {
|
|
clearInterval(client.disco.interval)
|
|
return 'clear'
|
|
}
|
|
|
|
let dbData = guildProfile.get('guildPlayer.disco')
|
|
let queue = useQueue(guild.id)
|
|
if (queue) if (queue.isPlaying()) {
|
|
dbData['progress'] = queue.node.playbackTime.toString()
|
|
|
|
guildProfile.set('guildPlayer.disco', dbData)
|
|
guildProfile.markModified('guildPlayer.disco')
|
|
await guildProfile.save().catch(console.error)
|
|
}
|
|
|
|
let channel = client.channels.cache.get(dbData.channelId) as TextChannel
|
|
if (!channel) {
|
|
console.log(`Aucun channel trouvé avec l'id \`${dbData.channelId}\`, veuillez utiliser la commande \`/database edit 'value': guildPlayer.disco.channelId\` !`)
|
|
clearInterval(client.disco.interval)
|
|
return 'clear'
|
|
}
|
|
|
|
let { embed, components } = await playerGenerate(guild)
|
|
if (components && embed.data.footer) embed.setFooter({ text: `Uptime: ${getUptime(client.uptime)} \n ${embed.data.footer.text}` })
|
|
else embed.setFooter({ text: `Uptime: ${getUptime(client.uptime)}` })
|
|
|
|
let messages = await channel.messages.fetch()
|
|
messages.forEach(msg => { if (!bots.includes(msg.author.id)) msg.delete() })
|
|
|
|
let botMessage = messages.find(msg => client.user && msg.author.id === client.user.id)
|
|
if (botMessage) {
|
|
if (!components && botMessage.components.length > 0) {
|
|
await botMessage.delete()
|
|
return channel.send({ embeds: [embed] })
|
|
|
|
} else if (components) return botMessage.edit({ embeds: [embed], components })
|
|
|
|
else return botMessage.edit({ embeds: [embed] })
|
|
|
|
} else return channel.send({ embeds: [embed] })
|
|
} catch (error) {
|
|
console.error(error);
|
|
return 'clear'
|
|
}
|
|
}
|
|
|
|
export async function playerEdit (interaction: ButtonInteraction) {
|
|
let guild = interaction.guild
|
|
if (!guild) return await interaction.reply({ content: 'Cette commande n\'est pas disponible en message privé.', ephemeral: true })
|
|
|
|
let { components } = await playerGenerate(guild)
|
|
if (!components) return
|
|
|
|
components.forEach((actionRow) => actionRow.components.forEach((button) => button.setDisabled(true)))
|
|
await interaction.update({ components })
|
|
}
|
|
|
|
export async function playerGenerate (guild: Guild) {
|
|
let embed = new EmbedBuilder().setColor('#ffc370')
|
|
|
|
let queue = useQueue(guild.id)
|
|
if (!queue) {
|
|
embed.setTitle('Aucune session d\'écoute en cours !')
|
|
return ({ embed, components: null })
|
|
}
|
|
|
|
let track = queue.currentTrack
|
|
if (!track) {
|
|
embed.setTitle('Aucune musique en cours de lecture !')
|
|
return ({ embed, components: null })
|
|
}
|
|
|
|
embed.setTitle(track.title)
|
|
.setAuthor({ name: track.author })
|
|
.setURL(track.url)
|
|
.setImage(track.thumbnail)
|
|
.addFields(
|
|
{ name: 'Durée', value: track.duration, inline: true },
|
|
{ name: 'Source', value: track.source === 'youtube' ? 'Youtube' : track.source === 'spotify' ? 'Spotify' : 'Inconnu', inline: true },
|
|
{ name: 'Volume', value: `${queue.node.volume}%`, inline: true },
|
|
{ name: queue.node.isPaused() ? 'Progression (en pause)' : 'Progression', value: queue.node.createProgressBar() || 'Aucune' },
|
|
{ name: 'Loop', value: queue.repeatMode === 3 ? 'Autoplay' : queue.repeatMode === 2 ? 'File d\'Attente' : queue.repeatMode === 1 ? 'Titre' : 'Off', inline: true }
|
|
)
|
|
.setDescription(`**Musique suivante :** ${queue.tracks.data[0] ? queue.tracks.data[0].title : 'Aucune'}`)
|
|
.setFooter({ text: `Demandé par ${track.requestedBy ? track.requestedBy.tag : 'Inconnu'}` })
|
|
|
|
let components = [
|
|
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
new ButtonBuilder()
|
|
.setLabel(queue.node.isPaused() ? '▶️' : '⏸️')
|
|
.setStyle(2)
|
|
.setCustomId(queue.node.isPaused() ? 'resume' : 'pause'),
|
|
new ButtonBuilder()
|
|
.setLabel('⏹️')
|
|
.setStyle(2)
|
|
.setCustomId('stop'),
|
|
new ButtonBuilder()
|
|
.setLabel('⏭️')
|
|
.setStyle(2)
|
|
.setCustomId('skip')
|
|
.setDisabled(queue.tracks.data.length !== 0),
|
|
new ButtonBuilder()
|
|
.setLabel('🔉')
|
|
.setStyle(2)
|
|
.setCustomId('volume_down')
|
|
.setDisabled(queue.node.volume === 0),
|
|
new ButtonBuilder()
|
|
.setLabel('🔊')
|
|
.setStyle(2)
|
|
.setCustomId('volume_up')
|
|
.setDisabled(queue.node.volume === 100)
|
|
),
|
|
new ActionRowBuilder<ButtonBuilder>().addComponents(
|
|
new ButtonBuilder()
|
|
.setLabel('🔀')
|
|
.setStyle(2)
|
|
.setCustomId('shuffle'),
|
|
new ButtonBuilder()
|
|
.setLabel('🔁')
|
|
.setStyle(2)
|
|
.setCustomId('loop'),
|
|
new ButtonBuilder()
|
|
.setLabel('⏮️')
|
|
.setStyle(2)
|
|
.setCustomId('previous')
|
|
.setDisabled(queue.history.previousTrack ? false : true)
|
|
)
|
|
]
|
|
return ({ embed, components })
|
|
}
|
|
|
|
export async function playerReplay (client: Client, guildProfile: Document) {
|
|
let dbData = guildProfile.get('guildPlayer.replay')
|
|
|
|
let textChannel = client.channels.cache.get(dbData.textChannelId) as TextChannel
|
|
if (!textChannel) return console.log(`Aucun channel trouvé avec l'id \`${dbData.textChannelId}\`, veuillez utiliser la commande \`/setchannel\` !`)
|
|
let voiceChannel = client.channels.cache.get(dbData.voiceChannelId) as VoiceChannel
|
|
if (!voiceChannel) return console.log(`Aucun channel trouvé avec l'id \`${dbData.voiceChannelId}\`, veuillez utiliser la commande \`/setchannel\` !`)
|
|
|
|
let player = useMainPlayer()
|
|
let queue = player.nodes.create(textChannel.guild, {
|
|
metadata: {
|
|
channel: textChannel,
|
|
client: textChannel.guild.members.me,
|
|
requestedBy: client.user
|
|
},
|
|
selfDeaf: true,
|
|
volume: 20,
|
|
leaveOnEmpty: true,
|
|
leaveOnEmptyCooldown: 30000,
|
|
leaveOnEnd: true,
|
|
leaveOnEndCooldown: 300000
|
|
})
|
|
|
|
try { if (!queue.connection) await queue.connect(voiceChannel) }
|
|
catch (error) { console.error(error) }
|
|
|
|
let result = await player.search(dbData.trackUrl as string, { requestedBy: client.user || undefined })
|
|
if (!result.hasTracks()) await textChannel.send(`Aucune musique trouvée pour **${dbData.trackUrl}** !`)
|
|
let track = result.tracks[0]
|
|
|
|
let entry = queue.tasksQueue.acquire()
|
|
await entry.getTask()
|
|
queue.addTrack(track)
|
|
|
|
try {
|
|
await queue.node.play()
|
|
await queue.node.seek(Number(dbData.progress) / 1000)
|
|
await textChannel.send(`Relancement de la musique suite à mon redémarrage...`)
|
|
} catch (error) { console.error(error) }
|
|
finally { queue.tasksQueue.release() }
|
|
} |