Version 1.0.2 - STABLE - Backend complété et prêt à l'usage

This commit is contained in:
2025-05-05 19:48:47 +02:00
parent 3aa4201dd2
commit e686edb0e6
23 changed files with 317 additions and 170 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "chopin-backend", "name": "chopin-backend",
"version": "1.0.1", "version": "1.0.2",
"description": "Discord Bot for music - Fetching everywhere !", "description": "Discord Bot for music - Fetching everywhere !",
"main": "src/main.js", "main": "src/main.js",
"nodemonConfig": { "nodemonConfig": {

View File

@@ -10,7 +10,7 @@ const command = new Command("about", "Affiche des informations sur le bot", (cli
const minutes = Math.floor((uptime % 3600) / 60); const minutes = Math.floor((uptime % 3600) / 60);
const seconds = Math.floor(uptime % 60); const seconds = Math.floor(uptime % 60);
const embed = new Embed() const embed = new Embed(interaction)
embed.setColor(237, 12, 91) embed.setColor(237, 12, 91)
embed.setThumbnail("https://cdn.discordapp.com/avatars/" + client.user.id + "/" + client.user.avatar + ".png") embed.setThumbnail("https://cdn.discordapp.com/avatars/" + client.user.id + "/" + client.user.avatar + ".png")
embed.setTitle('Subsonics - Chopin') embed.setTitle('Subsonics - Chopin')
@@ -31,7 +31,7 @@ const command = new Command("about", "Affiche des informations sur le bot", (cli
embed.addField('Ytdl', packageJson.dependencies["@distube/ytdl-core"].replace("^", ""),true) embed.addField('Ytdl', packageJson.dependencies["@distube/ytdl-core"].replace("^", ""),true)
embed.addColumn() embed.addColumn()
embed.send(interaction) embed.send()
}) })

View File

@@ -3,7 +3,7 @@ const { Embed } = require('../Embed');
const command = new Command("help", "Affiche la liste des commandes", (client, interaction) => { const command = new Command("help", "Affiche la liste des commandes", (client, interaction) => {
const embed = new Embed() const embed = new Embed(interaction)
embed.setColor(0x03ff2d) embed.setColor(0x03ff2d)
embed.setTitle('Comment assister au concert ?') embed.setTitle('Comment assister au concert ?')
embed.setDescription("**Eh ! Tu as eu ton ticket ? Tant mieux ! Voici la liste des commandes à utiliser dans le salon prévu à cet effet !**") embed.setDescription("**Eh ! Tu as eu ton ticket ? Tant mieux ! Voici la liste des commandes à utiliser dans le salon prévu à cet effet !**")
@@ -28,7 +28,7 @@ const command = new Command("help", "Affiche la liste des commandes", (client, i
}) })
embed.addField("La queue et la gestion du redémarrage se fait par le site https://subsonics.raphix.fr/", ":star:" ) embed.addField("La queue et la gestion du redémarrage se fait par le site https://subsonics.raphix.fr/", ":star:" )
embed.setThumbnail("https://static.wikia.nocookie.net/codelyoko/images/9/95/Subdigitals.jpg/revision/latest/scale-to-width-down/180?cb=20120105180510&path-prefix=fr"); embed.setThumbnail("https://static.wikia.nocookie.net/codelyoko/images/9/95/Subdigitals.jpg/revision/latest/scale-to-width-down/180?cb=20120105180510&path-prefix=fr");
embed.send(interaction) embed.send()
}) })
module.exports = {command} module.exports = {command}

View File

@@ -3,7 +3,7 @@ const {Embed, EmbedError} = require("../Embed")
const {Button} = require("../Button") const {Button} = require("../Button")
const command = new Command("invite", "Invite moi sur d'autres serveurs", (client, interaction) => { const command = new Command("invite", "Invite moi sur d'autres serveurs", (client, interaction) => {
const embed = new Embed() const embed = new Embed(interaction)
embed.setColor(0xFF007F) embed.setColor(0xFF007F)
embed.setTitle('**Inviter le bot sur d\'autres serveurs**') embed.setTitle('**Inviter le bot sur d\'autres serveurs**')
embed.setDescription('Vous pouvez m\'inviter sur d\'autres serveurs en cliquant sur le bouton ci-dessous.') embed.setDescription('Vous pouvez m\'inviter sur d\'autres serveurs en cliquant sur le bouton ci-dessous.')
@@ -13,7 +13,7 @@ const command = new Command("invite", "Invite moi sur d'autres serveurs", (clien
const linkButton = new Button("Invite", null, 5, "https://discord.com/oauth2/authorize?client_id=" + client.user.id + "&scope=bot+applications.commands&permissions=8") const linkButton = new Button("Invite", null, 5, "https://discord.com/oauth2/authorize?client_id=" + client.user.id + "&scope=bot+applications.commands&permissions=8")
embed.addButton(linkButton) embed.addButton(linkButton)
embed.send(interaction) embed.send()
}) })

View File

@@ -4,11 +4,15 @@ const {Player, AllPlayers} = require("../../player/Player")
const command = new Command("leave", "Quitter le salon vocal", (client, interaction) => { const command = new Command("leave", "Quitter le salon vocal", (client, interaction) => {
if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour arrêter le bot !").send(interaction) if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour arrêter le bot !", interaction)
const channel = interaction.member.voice.channel const channel = interaction.member.voice.channel
var embed = new Embed() var embed = new Embed(interaction)
if(AllPlayers.has(channel.guildId)) { if(AllPlayers.has(channel.guildId)) {
const player = AllPlayers.get(channel.guildId) const player = AllPlayers.get(channel.guildId)
if(!player?.connected) {
return embed.returnError("Le bot n'est pas connecté à ce salon vocal")
}
player.leave() player.leave()
@@ -16,12 +20,14 @@ const command = new Command("leave", "Quitter le salon vocal", (client, interact
embed.setTitle('**Déconnexion**') embed.setTitle('**Déconnexion**')
embed.setDescription('Déconnexion du salon vocal') embed.setDescription('Déconnexion du salon vocal')
embed.setThumbnail("https://www.iconsdb.com/icons/download/white/phone-51-64.png") embed.setThumbnail("https://www.iconsdb.com/icons/download/white/phone-51-64.png")
embed.send()
} else { } else {
embed = new EmbedError("Le bot n'est pas connecté à ce salon vocal") embed.returnError("Le bot n'est pas connecté à ce salon vocal")
} }
embed.send(interaction)
}) })

View File

@@ -5,13 +5,16 @@ const { Song } = require('../../player/Song');
const command = new Command("media", "Lire un média MP3/WAV dans un salon vocal", async (client, interaction) => { const command = new Command("media", "Lire un média MP3/WAV dans un salon vocal", async (client, interaction) => {
if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour jouer un média !").send(interaction, true) if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour jouer un média !", interaction, true)
const media = interaction.options.get("media") const media = interaction.options.get("media")
const now = interaction.options.getBoolean("now") || false const now = interaction.options.getBoolean("now") || false
if(media.attachment.contentType != "audio/mpeg" && media.attachment.contentType != "audio/wav") return new EmbedError("Le média doit être un fichier audio MP3 ou WAV !").send(interaction) if(media.attachment.contentType != "audio/mpeg" && media.attachment.contentType != "audio/wav") return new EmbedError("Le média doit être un fichier audio MP3 ou WAV !", interaction)
const embed = new Embed(interaction)
embed.setColor(0x15e6ed)
const channel = interaction.member.voice.channel const channel = interaction.member.voice.channel
const song = new Song() const song = new Song()
await song.processMedia(media, interaction.user.username) await song.processMedia(media, interaction.user.username)
@@ -19,8 +22,7 @@ const command = new Command("media", "Lire un média MP3/WAV dans un salon vocal
const player = new Player(channel.guildId) const player = new Player(channel.guildId)
player.join(channel) player.join(channel)
const embed = new Embed()
embed.setColor(0x15e6ed)
if(now) { if(now) {
@@ -40,7 +42,7 @@ const command = new Command("media", "Lire un média MP3/WAV dans un salon vocal
embed.setThumbnail(song.thumbnail) embed.setThumbnail(song.thumbnail)
embed.send(interaction) embed.send()
}, [{type: "FILE", name: "media", description: "Fichier audio à lire", required: true}, }, [{type: "FILE", name: "media", description: "Fichier audio à lire", required: true},

View File

@@ -5,20 +5,20 @@ const { Player } = require("../../player/Player")
const command = new Command("pause", "Mettre en pause / Reprendre la musique en cours", (client, interaction) => { const command = new Command("pause", "Mettre en pause / Reprendre la musique en cours", (client, interaction) => {
if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour mettre en pause la musique !").send(interaction) if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour mettre en pause la musique !", interaction)
const channel = interaction.member.voice.channel const channel = interaction.member.voice.channel
const player = new Player(channel.guildId) const player = new Player(channel.guildId)
const result = player.pause() const result = player.pause()
var embed = new Embed() var embed = new Embed(interaction)
embed.setColor(0x03ff2d) embed.setColor(0x03ff2d)
result.then((pause) => { result.then((pause) => {
if(pause == "no_music") { if(pause == "no_music") {
embed = new EmbedError("Il n'y a pas de musique en cours de lecture") embed.returnError("Il n'y a pas de musique en cours de lecture")
} else if(pause) { } else if(pause) {
embed.setTitle('Musique en pause') embed.setTitle('Musique en pause')
@@ -32,7 +32,7 @@ const command = new Command("pause", "Mettre en pause / Reprendre la musique en
embed.setThumbnail("https://www.iconsdb.com/icons/download/white/play-64.png") embed.setThumbnail("https://www.iconsdb.com/icons/download/white/play-64.png")
} }
embed.send(interaction) embed.send()
}) })
// Réponse en embed // Réponse en embed

View File

@@ -7,18 +7,19 @@ const spotify = require("../../media/SpotifyInformation");
const command = new Command("play", "Jouer une musique à partir d'un lien dans un salon vocal", async (client, interaction) => { const command = new Command("play", "Jouer une musique à partir d'un lien dans un salon vocal", async (client, interaction) => {
if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour jouer une musique !").send(interaction) if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour jouer une musique !", interaction)
const url = interaction.options.get("url") const url = interaction.options.get("url")
const channel = interaction.member.voice.channel const channel = interaction.member.voice.channel
const now = interaction.options.getBoolean("now") || false const now = interaction.options.getBoolean("now") || false
const embed = new Embed(interaction)
await Finder.search(url.value).then(async (song) => { await Finder.search(url.value).then(async (song) => {
if(!song) return new EmbedError("Impossible de trouver la musique à partir du lien donné ou des mots clés donnés").send(interaction) if(!song) return embed.returnError("Impossible de trouver la musique à partir du lien donné ou des mots clés donnés")
const player = new Player(channel.guildId) const player = new Player(channel.guildId)
player.join(channel) player.join(channel)
const embed = new Embed()
embed.setColor(0x15e6ed) embed.setColor(0x15e6ed)
// Check if song is playlist // Check if song is playlist
@@ -56,7 +57,7 @@ const command = new Command("play", "Jouer une musique à partir d'un lien dans
embed.setTitle("Ajoutée à la file d'attente") embed.setTitle("Ajoutée à la file d'attente")
} }
embed.send(interaction) embed.send()
if(song instanceof Playlist) { if(song instanceof Playlist) {
if(song.type == "spotify") { if(song.type == "spotify") {

View File

@@ -4,9 +4,10 @@ const { Player, AllPlayers } = require("../../player/Player")
const command = new Command("previous", "Passe à la musique précédente", (client, interaction) => { const command = new Command("previous", "Passe à la musique précédente", (client, interaction) => {
if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour passer à la musique suivante !").send(interaction) if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour passer à la musique suivante !", interaction)
const channel = interaction.member.voice.channel const channel = interaction.member.voice.channel
var embed = new Embed(interaction)
if(AllPlayers.has(channel.guildId)) { if(AllPlayers.has(channel.guildId)) {
@@ -14,34 +15,33 @@ const command = new Command("previous", "Passe à la musique précédente", (cli
const result = player.previous() const result = player.previous()
var embed = new Embed()
embed.setColor(0x15e6ed) embed.setColor(0x15e6ed)
result.then((song) => { result.then((song) => {
if(song == "no_music") { if(song == "no_music") {
embed = new EmbedError("Il n'y a pas de musique précédemment jouée") embed.returnError("Il n'y a pas de musique précédemment jouée")
} else if(song) { } else if(song) {
// Result is a song // Result is a song
embed.setTitle('**Musique précédente !**') embed.setTitle('**Musique précédente !**')
embed.setDescription('**Titre : **' + song.title) embed.setDescription('**Titre : **' + song.title)
embed.addField('**Durée : **'+ song.readduration, "") embed.addField('**Durée : **'+ song.readduration, "")
embed.addField("**Artiste : **" + song.author, "") embed.addField("**Artiste : **" + song.author, "")
embed.setThumbnail(song.thumbnail) embed.setThumbnail(song.thumbnail)
embed.send()
} }
embed.send(interaction)
}) })
} else { } else {
return new EmbedError("Le bot n'est pas connecté").send(interaction) return embed.returnError("Le bot n'est pas connecté", interaction)
} }

View File

@@ -5,37 +5,38 @@ const { Player, AllPlayers } = require("../../player/Player")
const command = new Command("liste", "Affiche la file d'attente", (client, interaction) => { const command = new Command("liste", "Affiche la file d'attente", (client, interaction) => {
const channel = interaction.member.voice.channel const channel = interaction.member.voice.channel
var embed = new Embed(interaction)
if(AllPlayers.has(channel.guildId)) { if(AllPlayers.has(channel.guildId)) {
const player = new Player(channel.guildId) const player = new Player(channel.guildId)
const queue = player.queue.getNext() const queue = player.queue.getNext()
var embed = new Embed()
embed.setColor(0x15e6ed)
if(queue.length == 0) {
embed = new EmbedError("Il n'y a pas de musique en file d'attente")
} else if(queue.length > 0) {
if(queue.length == 0) {
embed.returnError("Il n'y a pas de musique en file d'attente")
// Result is a song } else if(queue.length > 0) {
embed.setColor(0x15e6ed)
embed.setThumbnail("https://www.iconsdb.com/icons/download/white/list-2-64.png") // Result is a song
embed.setTitle('**File d\'attente :**') embed.setColor(0x15e6ed)
embed.setDescription('**' + queue.length + ' musiques**') embed.setThumbnail("https://www.iconsdb.com/icons/download/white/list-2-64.png")
queue.forEach((song, index) => { embed.setTitle('**File d\'attente :**')
// max 24 fields embed.setDescription('**' + queue.length + ' musiques**')
if(index > 10) return queue.forEach((song, index) => {
embed.addField(`**${index+1} - ${song.title}**`, `**Durée : **${song.readduration}\n**Artiste : **${song.author}`) // max 24 fields
}) if(index > 10) return
embed.addField(`**${index+1} - ${song.title}**`, `**Durée : **${song.readduration}\n**Artiste : **${song.author}`)
} })
embed.send()
embed.send(interaction) }
} else { } else {
return new EmbedError("Le bot n'est pas connecté").send(interaction) embed.returnError("Le bot n'est pas connecté")
} }
}) })

View File

@@ -5,7 +5,7 @@ const { Report } = require('../ReportSender');
const command = new Command("report", "Signaler un problème avec le bot", (client, interaction) => { const command = new Command("report", "Signaler un problème avec le bot", (client, interaction) => {
const report = new Report(interaction.user.username, interaction.options.getString("type"), interaction.options.getString("description")) const report = new Report(interaction.user.username, interaction.options.getString("type"), interaction.options.getString("description"))
const result = report.send() const result = report.send()
const embed = new Embed() const embed = new Embed(interaction)
result.then((res) => { result.then((res) => {
@@ -20,7 +20,7 @@ const command = new Command("report", "Signaler un problème avec le bot", (clie
embed.setDescription("Votre rapport a bien été envoyé !") embed.setDescription("Votre rapport a bien été envoyé !")
} }
embed.send(interaction) embed.send()
}) })

View File

@@ -14,12 +14,12 @@ const command = new Command("restart", "Redémarre le bot", (client, interaction
} }
const reason = interaction.options.getString("reason") const reason = interaction.options.getString("reason")
restart(reason) restart(reason)
const embed = new Embed() const embed = new Embed(interaction)
embed.setColor(150, 20, 20) embed.setColor(150, 20, 20)
embed.setTitle('Redémarrage') embed.setTitle('Redémarrage')
embed.setDescription("Veuillez patientez, le bot va redémarrer dans un instant ! :arrows_counterclockwise:") embed.setDescription("Veuillez patientez, le bot va redémarrer dans un instant ! :arrows_counterclockwise:")
embed.addField('Raison', reason) embed.addField('Raison', reason)
embed.send(interaction) embed.send()
}, },
[{type: "STRING", name: "reason", description: "Raison du redémarrage", required: true}] [{type: "STRING", name: "reason", description: "Raison du redémarrage", required: true}]
) )

View File

@@ -4,22 +4,21 @@ const { Player, AllPlayers } = require("../../player/Player")
const command = new Command("skip", "Passe à la musique suivante", (client, interaction) => { const command = new Command("skip", "Passe à la musique suivante", (client, interaction) => {
if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour passer à la musique suivante !").send(interaction) if(!interaction.member.voice.channel) return new EmbedError("Vous devez rejoindre un salon vocal pour passer à la musique suivante !", interaction)
const channel = interaction.member.voice.channel const channel = interaction.member.voice.channel
var embed = new Embed(interaction)
if(AllPlayers.has(channel.guildId)) { if(AllPlayers.has(channel.guildId)) {
const player = new Player(channel.guildId) const player = new Player(channel.guildId)
const result = player.skip() const result = player.skip()
var embed = new Embed()
embed.setColor(0x15e6ed) embed.setColor(0x15e6ed)
result.then((song) => { result.then((song) => {
if(song == "no_music") { if(song == "no_music") {
embed = new EmbedError("Il n'y a pas de musique en file d'attente") embed.returnError("Il n'y a pas de musique en file d'attente", interaction)
} else if(song) { } else if(song) {
@@ -35,11 +34,11 @@ const command = new Command("skip", "Passe à la musique suivante", (client, int
} }
embed.send(interaction) embed.send()
}) })
} else { } else {
return new EmbedError("Le bot n'est pas connecté").send(interaction) return embed.returnError("Le bot n'est pas connecté", interaction)
} }

View File

@@ -8,14 +8,14 @@ const command = new Command("state", "Affiche la musique en cours", (client, int
const player = new Player(channel.guildId) const player = new Player(channel.guildId)
const song = player.queue.getCurrent() const song = player.queue.getCurrent()
var embed = new Embed()
embed.setColor(0x15e6ed)
if(!song) { if(!song) {
embed = new EmbedError("Il n'y a pas de musique en cours de lecture") var embed = new EmbedError("Il n'y a pas de musique en cours de lecture", interaction)
} else if(song) { } else if(song) {
var embed = new Embed(interaction)
// Result is a song // Result is a song
embed.setColor(0x15e6ed) embed.setColor(0x15e6ed)
@@ -25,10 +25,10 @@ const command = new Command("state", "Affiche la musique en cours", (client, int
embed.addField("**Artiste : **", song.author) embed.addField("**Artiste : **", song.author)
embed.setThumbnail(song.thumbnail) embed.setThumbnail(song.thumbnail)
embed.send()
} }
embed.send(interaction)
}) })
module.exports = {command} module.exports = {command}

View File

@@ -4,7 +4,7 @@ const { Embed } = require('../Embed');
const config = require('../../utils/Database/Configuration') const config = require('../../utils/Database/Configuration')
const command = new Command("web", "Affiche le lien vers le site web pour contrôler le bot", (client, interaction) => { const command = new Command("web", "Affiche le lien vers le site web pour contrôler le bot", (client, interaction) => {
const embed = new Embed() const embed = new Embed(interaction)
embed.setColor(0xffffff) embed.setColor(0xffffff)
embed.setTitle('Subsonics - Chopin') embed.setTitle('Subsonics - Chopin')
embed.addBotPicture(client) embed.addBotPicture(client)
@@ -13,7 +13,7 @@ const command = new Command("web", "Affiche le lien vers le site web pour contr
const linkButton = new Button("Site web", null, 5, config.getWebsiteLink()) const linkButton = new Button("Site web", null, 5, config.getWebsiteLink())
embed.addButton(linkButton) embed.addButton(linkButton)
embed.send(interaction) embed.send()
}) })

View File

@@ -3,10 +3,18 @@ const { EmbedBuilder, ActionRowBuilder } = require("discord.js");
class Embed { class Embed {
fields; fields;
buttons; buttons;
constructor() { constructor (interaction, ephemeral) {
this.embed = new EmbedBuilder().setTimestamp() this.embed = new EmbedBuilder().setTimestamp()
this.fields = [] this.fields = []
this.buttons = [] this.buttons = []
this.isSended = false
if(interaction) {
interaction.deferReply({ ephemeral: ephemeral }).then(() => {
this.isSended = true
})
this.interaction = interaction
this.ephemeral = ephemeral
}
} }
setTitle(title) { setTitle(title) {
@@ -92,19 +100,32 @@ class Embed {
return this.embed return this.embed
} }
send(interaction, ephemeral) { async send() {
if(ephemeral === undefined) ephemeral = false; // Add a secutiry check to avoid sending an embed if the interaction is not defined and retry one again
interaction.reply({ embeds: [this.build()], ephemeral: ephemeral, components: this.buttons.length > 0 ? [this.actionRow] : [] }) while(!this.isSended) {
await new Promise(resolve => setTimeout(resolve, 50));
}
if(this.ephemeral === undefined) this.ephemeral = false;
this.interaction.editReply({ embeds: [this.build()], components: this.buttons.length > 0 ? [this.actionRow] : [] })
} }
}
class EmbedError extends Embed { async returnError(message) {
constructor(message) {
super()
this.setColor(150, 20, 20) this.setColor(150, 20, 20)
this.setTitle('Erreur') this.setTitle('Erreur')
this.setThumbnail("https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Dialog-error-round.svg/2048px-Dialog-error-round.svg.png") this.setThumbnail("https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Dialog-error-round.svg/2048px-Dialog-error-round.svg.png")
this.setDescription(message) this.setDescription(message)
await this.send()
}
}
class EmbedError extends Embed {
constructor(message, interaction, ephemeral) {
super(interaction, ephemeral)
this.setColor(150, 20, 20)
this.setTitle('Erreur')
this.setThumbnail("https://upload.wikimedia.org/wikipedia/commons/thumb/9/97/Dialog-error-round.svg/2048px-Dialog-error-round.svg.png")
this.setDescription(message)
this.send()
} }
} }

View File

@@ -76,7 +76,7 @@ async function search(query, multiple, forceType) {
return await soundcloud.getPlaylist(query) return await soundcloud.getPlaylist(query)
} }
// TODO: Add more providers //MORELATER: Add more providers
} }
module.exports = {search} module.exports = {search}

View File

@@ -204,6 +204,11 @@ class List {
} }
moveNext(fromIndex, toIndex) { moveNext(fromIndex, toIndex) {
// Check if fromIndex and toIndex are valid
if(fromIndex < 0 || fromIndex >= this.next.length + 1 || toIndex < 0 || toIndex >= this.next.length + 1) {
clog.error("Impossible de déplacer la musique, car l'index est invalide, GuildId : " + this.guildId)
return
}
if(fromIndex == toIndex) return; if(fromIndex == toIndex) return;
const song = this.next[fromIndex] const song = this.next[fromIndex]
this.next.splice(fromIndex, 1) this.next.splice(fromIndex, 1)

View File

@@ -1,6 +1,7 @@
const { joinVoiceChannel, getVoiceConnection, VoiceConnectionStatus, createAudioPlayer, AudioPlayerStatus, StreamType, createAudioResource } = require('@discordjs/voice'); const { joinVoiceChannel, getVoiceConnection, VoiceConnectionStatus, createAudioPlayer, AudioPlayerStatus, StreamType, createAudioResource } = require('@discordjs/voice');
const {List} = require('./List') const {List} = require('./List')
const {LogType} = require("loguix"); const {LogType} = require("loguix");
const songCheck = require('./SongCheck')
const ffmpeg = require('fluent-ffmpeg') const ffmpeg = require('fluent-ffmpeg')
const fs = require('fs') const fs = require('fs')
const { PassThrough } = require('stream'); const { PassThrough } = require('stream');
@@ -91,6 +92,7 @@ class Player {
}); });
this.player.on(AudioPlayerStatus.Idle, () => { this.player.on(AudioPlayerStatus.Idle, () => {
if(this.checkConnection()) return
// Si la musique est en boucle, on relance la musique // Si la musique est en boucle, on relance la musique
if(this.loop) { if(this.loop) {
this.play(this.queue.current) this.play(this.queue.current)
@@ -106,7 +108,7 @@ class Player {
}); });
this.player.on(AudioPlayerStatus.Playing, () => { this.player.on(AudioPlayerStatus.Playing, () => {
if(this.checkConnection()) return
plog.log(`GUILD : ${this.guildId} - Le player est en train de jouer le contenu suivant : ${this.queue.current.title}`); plog.log(`GUILD : ${this.guildId} - Le player est en train de jouer le contenu suivant : ${this.queue.current.title}`);
Activity.setMusicActivity(this.queue.current.title, this.queue.current.author, this.queue.current.thumbnail) Activity.setMusicActivity(this.queue.current.title, this.queue.current.author, this.queue.current.thumbnail)
process.emit("PLAYERS_UPDATE") process.emit("PLAYERS_UPDATE")
@@ -140,7 +142,8 @@ class Player {
duration: this.getDuration(), duration: this.getDuration(),
playerState: playerStatus, playerState: playerStatus,
connectionState: connectionStatus, connectionState: connectionStatus,
channelId: this.channelId channelId: this.channelId,
guildId: this.guildId,
} }
return state return state
} }
@@ -168,6 +171,7 @@ class Player {
} }
async play(song) { async play(song) {
if(!songCheck.checkSong(song)) return
if(this.checkConnection()) return if(this.checkConnection()) return
if(this.queue.current != null) { if(this.queue.current != null) {
this.player.stop() this.player.stop()
@@ -202,7 +206,7 @@ class Player {
} }
async add(song) { async add(song) {
if(this.player.state.status == AudioPlayerStatus.Idle && this.queue.current === null && this.queue.next.length === 0) { if(this.player?.state?.status == AudioPlayerStatus.Idle && this.queue.current === null && this.queue.next.length === 0) {
this.play(song) this.play(song)
return return
} }
@@ -212,15 +216,14 @@ class Player {
} }
async readPlaylist(playlist, now) { async readPlaylist(playlist, now) {
if(this.player.state.status == AudioPlayerStatus.Idle && this.queue.current === null && this.queue.next.length === 0) { if(this.player?.state?.status == AudioPlayerStatus.Idle && this.queue.current === null && this.queue.next.length === 0) {
this.play(playlist.songs[0])
}
if(now) {
this.play(playlist.songs[0]) this.play(playlist.songs[0])
this.queue.addNextPlaylist(playlist, true) this.queue.addNextPlaylist(playlist, true)
} else { return
this.queue.addNextPlaylist(playlist) }
} if(now) this.play(playlist.songs[0])
this.queue.addNextPlaylist(playlist, now)
plog.log(`GUILD : ${this.guildId} - La playlist a été ajoutée à la liste de lecture : ${playlist.title}`) plog.log(`GUILD : ${this.guildId} - La playlist a été ajoutée à la liste de lecture : ${playlist.title}`)
} }
@@ -229,13 +232,15 @@ class Player {
if(this.player.state.status == AudioPlayerStatus.Paused) { if(this.player.state.status == AudioPlayerStatus.Paused) {
this.player.unpause() this.player.unpause()
plog.log(`GUILD : ${this.guildId} - La musique a été reprise`) plog.log(`GUILD : ${this.guildId} - La musique a été reprise`)
process.emit("PLAYERS_UPDATE")
return false return false
} else { } else {
this.player.pause() this.player.pause()
plog.log(`GUILD : ${this.guildId} - La musique a été mise en pause`) plog.log(`GUILD : ${this.guildId} - La musique a été mise en pause`)
process.emit("PLAYERS_UPDATE")
return true return true
} }
process.emit("PLAYERS_UPDATE")
} }
async leave() { async leave() {
@@ -260,7 +265,7 @@ class Player {
} }
async setDuration(duration) { async setDuration(duration) {
//FIXME: SET DURATION FONCTIONNE TRES LENTEMENT
if (this.checkConnection()) return; if (this.checkConnection()) return;
if (this.queue.current == null) return; if (this.queue.current == null) return;
if (this.currentResource == null) return; if (this.currentResource == null) return;

View File

@@ -0,0 +1,44 @@
const {LogType} = require("loguix")
const {Song} = require("./Song")
const slog = new LogType("SongCheck")
function checkSong(song) {
if(!(song instanceof Song)) {
slog.error("La musique n'est pas une instance de la classe Song")
// Check if the song is valid and if it has all the required properties
if(song.title && song.id && song.author && song.url && song.duration && song.readduration && song.type) {
slog.log("Acceptation de la musique : " + song.title)
return true
} else {
slog.error("La musique n'est pas valide")
return false
}
}
if(!song.url) {
slog.error("La musique n'a pas d'url")
return false
}
if(!song.title) {
slog.error("La musique n'a pas de titre")
return false
}
if(!song.author) {
slog.error("La musique n'a pas d'auteur")
return false
}
if(!song.duration) {
slog.error("La musique n'a pas de durée")
return false
}
if(!song.readduration) {
slog.error("La musique n'a pas de durée lisible")
return false
}
if(!song.type) {
slog.error("La musique n'a pas de type")
return false
}
return true
}
module.exports = {checkSong}

View File

@@ -1,3 +1,5 @@
const { getReadableDuration } = require("../utils/TimeConverter");
class Playlist { class Playlist {
title = "Aucun titre"; title = "Aucun titre";
id; id;
@@ -17,8 +19,11 @@ class Playlist {
this.authorId = authorId; this.authorId = authorId;
this.songs = songs || new Array(); this.songs = songs || new Array();
this.thumbnail = thumbnail; this.thumbnail = thumbnail;
this.duration = duration; // Make the some of durations of the songs
this.readduration = readduration; if(this.songs.length > 0) {
this.duration = this.songs.reduce((acc, song) => acc + song.duration, 0);
this.readduration = getReadableDuration(this.duration);
}
this.description = description; this.description = description;
if(!this.url) { if(!this.url) {
this.type = "playlist"; this.type = "playlist";

View File

@@ -42,6 +42,7 @@ function init() {
for(var guild of discordBot.getGuilds().keys()) { for(var guild of discordBot.getGuilds().keys()) {
const player = players.getPlayer(guild) const player = players.getPlayer(guild)
if(player) { if(player) {
if(!player.isConnected()) continue;
io.to(player.guildId).emit("/PLAYER/UPDATE", player.getState()) io.to(player.guildId).emit("/PLAYER/UPDATE", player.getState())
wlog.log("Envoi de l'état du player de la guilde : " + player.guildId + " à tous les utilisateurs connectés") wlog.log("Envoi de l'état du player de la guilde : " + player.guildId + " à tous les utilisateurs connectés")
} }
@@ -68,8 +69,8 @@ function init() {
// Make sure Discord Bot is loaded and make an interruption until it is loaded // Make sure Discord Bot is loaded and make an interruption until it is loaded
while(!discordBot.getClient().isReady()) { while(!discordBot.getClient().isReady()) {
wlog.warn("Attente de traitement : "+ socket.id + " : Le bot Discord n'est pas encore chargé, attente de 1 seconde...") wlog.warn("Attente de traitement : "+ socket.id + " : Le bot Discord n'est pas encore chargé, attente de 3 seconde... (Avoid Rate Limit)")
await new Promise(resolve => setTimeout(resolve, 1000)) await new Promise(resolve => setTimeout(resolve, 3000))
} }
wlog.log(`Connexion d'un client : ${socket.id}`) wlog.log(`Connexion d'un client : ${socket.id}`)
@@ -152,8 +153,13 @@ function init() {
return return
} }
await users.updateGuilds(socketUser.identity.id) if (!(await users.updateGuilds(socketUser.identity.id)) || !(await users.updateIdentity(socketUser.identity.id))) {
await users.updateIdentity(socketUser.identity.id) wlog.error("Erreur lors de la mise à jour des informations de l'utilisateur : " + socketUser.identity.id);
socket.emit("UPDATE_ERROR", "Error updating user information");
wlog.log("Déconnexion de l'utilisateur : " + socketUser.identity.username + " (" + socketUser.identity.id + ") - Socket : " + socket.id)
socket.disconnect();
return;
}
} }
socketUser = users.getUserByToken(token) socketUser = users.getUserByToken(token)
@@ -220,14 +226,14 @@ function init() {
// PLAYERS // PLAYERS
//CHECKED : 03/05/2025
IORequest("/PLAYER/PREVIOUS/LIST", (guildId) => { IORequest("/PLAYER/PREVIOUS/LIST", (guildId) => {
if(!checkUserGuild(socketUser, guildId)) return if(!checkUserGuild(socketUser, guildId)) return
const list = new List(guildId) const list = new List(guildId)
IOAnswer("/PLAYER/PREVIOUS/LIST", list.getPrevious()) IOAnswer("/PLAYER/PREVIOUS/LIST", list.getPrevious())
}) })
//TODO: Faire les autres reqêtes sur la liste // ChECKED : 03/05/2025
IORequest("/PLAYER/JOIN", (guildId) => { IORequest("/PLAYER/JOIN", (guildId) => {
if(!checkUserGuild(socketUser, guildId)) return if(!checkUserGuild(socketUser, guildId)) return
wlog.log("L'utilisateur '" + socketUser.identity.username + "' rejoint la liste d'écoute du player de la guilde : " + guildId) wlog.log("L'utilisateur '" + socketUser.identity.username + "' rejoint la liste d'écoute du player de la guilde : " + guildId)
@@ -238,37 +244,49 @@ function init() {
} }
}) })
socket.join(guildId) socket.join(guildId)
IOAnswer("PLAYER_STATE", true) IOAnswer("/PLAYER/JOIN", true)
process.emit("PLAYERS_UPDATE")
}) })
IORequest("/PLAYER/STATE", (guildId) => { // CHECKED : 03/05/2025
handlePlayerAction(guildId, async (player) => await player.getState(), "/PLAYER/STATE"); IORequest("/PLAYER/STATE", async (guildId) => {
const player = await verifyPlayerAction(guildId)
if(!player) return IOAnswer("/PLAYER/STATE", false)
IOAnswer("/PLAYER/STATE", await player.getState())
}) })
// CHECKED : 03/05/2025
IORequest("/PLAYER/PAUSE", (guildId) => { IORequest("/PLAYER/PAUSE", (guildId) => {
handlePlayerAction(guildId, (player) => player.pause(), "/PLAYER/PAUSE"); handlePlayerAction(guildId, (player) => player.pause(), "/PLAYER/PAUSE");
}); });
// CHECKED : 03/05/2025
IORequest("/PLAYER/BACKWARD", (guildId) => { IORequest("/PLAYER/BACKWARD", (guildId) => {
handlePlayerAction(guildId, (player) => player.previous(), "/PLAYER/BACKWARD"); handlePlayerAction(guildId, (player) => player.previous(), "/PLAYER/BACKWARD");
}); });
// CHECKED : 03/05/2025
IORequest("/PLAYER/FORWARD", (guildId) => { IORequest("/PLAYER/FORWARD", (guildId) => {
handlePlayerAction(guildId, (player) => player.skip(), "/PLAYER/FORWARD"); handlePlayerAction(guildId, (player) => player.skip(), "/PLAYER/FORWARD");
}); });
// CHECKED : 03/05/2025
IORequest("/PLAYER/LOOP", (guildId) => { IORequest("/PLAYER/LOOP", (guildId) => {
handlePlayerAction(guildId, (player) => player.setLoop(), "/PLAYER/LOOP"); handlePlayerAction(guildId, (player) => player.setLoop(), "/PLAYER/LOOP");
}); });
// CHECKED : 03/05/2025
IORequest("/PLAYER/SHUFFLE", (guildId) => { IORequest("/PLAYER/SHUFFLE", (guildId) => {
handlePlayerAction(guildId, (player) => player.setShuffle(), "/PLAYER/SHUFFLE"); handlePlayerAction(guildId, (player) => player.setShuffle(), "/PLAYER/SHUFFLE");
}); });
// CHECKED : 03/05/2025
IORequest("/PLAYER/DISCONNECT", (guildId) => { IORequest("/PLAYER/DISCONNECT", (guildId) => {
handlePlayerAction(guildId, (player) => player.leave(), "/PLAYER/DISCONNECT"); handlePlayerAction(guildId, (player) => player.leave(), "/PLAYER/DISCONNECT");
}); });
// CHECKED : 03/05/2025
IORequest("/PLAYER/CHANNEL/CHANGE", (guildId) => { IORequest("/PLAYER/CHANNEL/CHANGE", (guildId) => {
handlePlayerAction(guildId, (player) => { handlePlayerAction(guildId, (player) => {
const channel = getUserChannel() const channel = getUserChannel()
@@ -280,6 +298,7 @@ function init() {
}, "/PLAYER/CHANNEL/CHANGE"); }, "/PLAYER/CHANNEL/CHANGE");
}); });
// CHECKED : 03/05/2025
IORequest("/PLAYER/SEEK", (data) => { IORequest("/PLAYER/SEEK", (data) => {
if(!data) return IOAnswer("/PLAYER/SEEK", false) if(!data) return IOAnswer("/PLAYER/SEEK", false)
const {guildId, time} = data const {guildId, time} = data
@@ -296,14 +315,17 @@ function init() {
}, "/PLAYER/SEEK"); }, "/PLAYER/SEEK");
}); });
// CHECKED : 04/05/2025
IORequest("/QUEUE/PLAY/NOW", (data) => { IORequest("/QUEUE/PLAY/NOW", (data) => {
if(!data) return IOAnswer("/QUEUE/PLAY/NOW", false) if(!data) return IOAnswer("/QUEUE/PLAY/NOW", false)
const {guildId, song} = data const {guildId, index, listType} = data
if(!song) return IOAnswer("/QUEUE/PLAY/NOW", false) if(!index) return IOAnswer("/QUEUE/PLAY/NOW", false)
if(!guildId) return IOAnswer("/QUEUE/PLAY/NOW", false) if(!guildId) return IOAnswer("/QUEUE/PLAY/NOW", false)
if(!listType) return IOAnswer("/QUEUE/PLAY/NOW", false)
if(!checkUserGuild(socketUser, guildId)) return if(!checkUserGuild(socketUser, guildId)) return
const player = new Player(guildId) const player = new Player(guildId)
if(!connectToPlayer(guildId, player)) return IOAnswer("/QUEUE/PLAY", false) if(!connectToPlayer(guildId, player)) return IOAnswer("/QUEUE/PLAY", false)
var song;
if(listType == "previous") { if(listType == "previous") {
const previous = player.queue.getPrevious() const previous = player.queue.getPrevious()
song = previous[index] song = previous[index]
@@ -311,11 +333,13 @@ function init() {
const next = player.queue.getNext() const next = player.queue.getNext()
song = next[index] song = next[index]
} }
if(!song) return IOAnswer("/QUEUE/PLAY", false) if(!song) return IOAnswer("/QUEUE/PLAY/NOW", false)
player.add(song) if(listType == "next") player.queue.removeNextByIndex(index)
player.play(song)
IOAnswer("/QUEUE/PLAY/NOW", true) IOAnswer("/QUEUE/PLAY/NOW", true)
}) })
// CHECKED : 04/05/2025
IORequest("/QUEUE/NEXT/DELETE", (data) => { IORequest("/QUEUE/NEXT/DELETE", (data) => {
if(!data) return IOAnswer("/QUEUE/NEXT/DELETE", false) if(!data) return IOAnswer("/QUEUE/NEXT/DELETE", false)
const {guildId, index} = data const {guildId, index} = data
@@ -325,13 +349,15 @@ function init() {
const next = player.queue.getNext() const next = player.queue.getNext()
if(!next[index]) return IOAnswer("/QUEUE/NEXT/DELETE", false); if(!next[index]) return IOAnswer("/QUEUE/NEXT/DELETE", false);
player.queue.removeNextByIndex(index) player.queue.removeNextByIndex(index)
}) }, "/QUEUE/NEXT/DELETE")
}) })
// CHECKED : 04/05/2025
IORequest("/QUEUE/NEXT/DELETEALL", (guildId) => { IORequest("/QUEUE/NEXT/DELETEALL", (guildId) => {
handlePlayerAction(guildId, (player) => player.queue.clearNext()) handlePlayerAction(guildId, (player) => player.queue.clearNext(), "/QUEUE/NEXT/DELETEALL")
}) })
// CHECKED : 04/05/2025
IORequest("/QUEUE/NEXT/MOVE", (data) => { IORequest("/QUEUE/NEXT/MOVE", (data) => {
if(!data) return IOAnswer("/QUEUE/NEXT/MOVE", false) if(!data) return IOAnswer("/QUEUE/NEXT/MOVE", false)
const {guildId, index, newIndex} = data const {guildId, index, newIndex} = data
@@ -342,7 +368,7 @@ function init() {
const next = player.queue.getNext() const next = player.queue.getNext()
if(!next[index]) return IOAnswer("/QUEUE/NEXT/MOVE", false); if(!next[index]) return IOAnswer("/QUEUE/NEXT/MOVE", false);
player.queue.moveNext(index, newIndex) player.queue.moveNext(index, newIndex)
}) }, "/QUEUE/NEXT/MOVE")
}) })
// SEARCH // SEARCH
@@ -352,10 +378,14 @@ function init() {
IOAnswer("/SEARCH", await Finder.search(query, true)) IOAnswer("/SEARCH", await Finder.search(query, true))
}) })
// CHECKED : 03/05/2025
IORequest("/SEARCH/PLAY", async (data) => { IORequest("/SEARCH/PLAY", async (data) => {
if(!data) return IOAnswer("/SEARCH/PLAY", false) if(!data) return IOAnswer("/SEARCH/PLAY", false)
const {guildId, song, now} = data var {guildId, song, now} = data
if(!song) return IOAnswer("/SEARCH/PLAY", false) if(!song) return IOAnswer("/SEARCH/PLAY", false)
if(typeof song == "string") {
song = JSON.parse(song)
}
if(!guildId) return IOAnswer("/SEARCH/PLAY", false) if(!guildId) return IOAnswer("/SEARCH/PLAY", false)
if(!checkUserGuild(socketUser, guildId)) return if(!checkUserGuild(socketUser, guildId)) return
const player = new Player(guildId) const player = new Player(guildId)
@@ -368,6 +398,20 @@ function init() {
IOAnswer("/SEARCH/PLAY", true) IOAnswer("/SEARCH/PLAY", true)
}) })
// CHECKED : 05/05/2025
IORequest("/SEARCH/PLAYLIST", async (data) => {
if(!data) return IOAnswer("/SEARCH/PLAYLIST", false)
const {url, now, guildId} = data
if(!url) return IOAnswer("/SEARCH/PLAYLIST", false)
if(!guildId) return IOAnswer("/SEARCH/PLAYLIST", false)
const playlist = await Finder.search(url, true, "PLAYLIST")
if(!playlist) return IOAnswer("/SEARCH/PLAYLIST", false)
const player = new Player(guildId)
if(!connectToPlayer(guildId, player)) return IOAnswer("/SEARCH/PLAYLIST", false)
player.readPlaylist(playlist, now)
IOAnswer("/SEARCH/PLAYLIST", true)
})
// PLAYLISTS // PLAYLISTS
@@ -446,7 +490,8 @@ function init() {
IOAnswer("/PLAYLISTS/REMOVE_SONG", true) IOAnswer("/PLAYLISTS/REMOVE_SONG", true)
}) })
IORequest("/PLAYLISTS/PLAY", (data) => { // CHECKED : 05/05/2025
IORequest("/PLAYLISTS/PLAY", async (data) => {
if(!data) return IOAnswer("/PLAYLISTS/PLAY", false) if(!data) return IOAnswer("/PLAYLISTS/PLAY", false)
const {name, guildId, now} = data const {name, guildId, now} = data
if(!name || !guildId) return IOAnswer("/PLAYLISTS/PLAY", false) if(!name || !guildId) return IOAnswer("/PLAYLISTS/PLAY", false)
@@ -454,7 +499,7 @@ function init() {
const playlist = playlists.getPlaylistOfUser(socketUser.identity.id, name) const playlist = playlists.getPlaylistOfUser(socketUser.identity.id, name)
if(!playlist) return IOAnswer("/PLAYLISTS/PLAY", false) if(!playlist) return IOAnswer("/PLAYLISTS/PLAY", false)
const player = new Player(guildId) const player = new Player(guildId)
if(!connectToPlayer(guildId, player)) return IOAnswer("/PLAYLISTS/PLAY", false) if(!await connectToPlayer(guildId, player)) return IOAnswer("/PLAYLISTS/PLAY", false)
player.readPlaylist(playlist, now) player.readPlaylist(playlist, now)
IOAnswer("/PLAYLISTS/PLAY", true) IOAnswer("/PLAYLISTS/PLAY", true)
}) })
@@ -575,6 +620,7 @@ function init() {
const member = membersVoices.get(socketUser.identity.id) const member = membersVoices.get(socketUser.identity.id)
if(member) { if(member) {
const channelId = member.channelId const channelId = member.channelId
const guildId = member.guildId
const channel = discordBot.getChannel(guildId, channelId) const channel = discordBot.getChannel(guildId, channelId)
if(!channel) { if(!channel) {
wlog.warn("Le channel vocal n'existe pas : " + channelId) wlog.warn("Le channel vocal n'existe pas : " + channelId)
@@ -599,6 +645,17 @@ function init() {
return true return true
} }
async function verifyPlayerAction(guildId) {
if (!checkUserGuild(socketUser, guildId)) return null;
const player = players.getPlayer(guildId);
if (player) {
return player;
} else {
wlog.warn(`Le player de la guilde : ${guildId} n'existe pas`);
return null;
}
}
function checkUserGuild(socketUser, guildId) { function checkUserGuild(socketUser, guildId) {
// Check if the guildId is referenced in the bot guilds // Check if the guildId is referenced in the bot guilds
@@ -622,20 +679,22 @@ function init() {
return true return true
} }
/** /**
* @param {function(Player)} action - The action to perform on the player. * @param {function(Player)} action - The action to perform on the player.
*/ */
async function handlePlayerAction(guildId, action, actionName) { async function handlePlayerAction(guildId, action, actionName) {
if (!checkUserGuild(socketUser, guildId)) return; if (!checkUserGuild(socketUser, guildId)) return;
const player = players.getPlayer(guildId); const player = players.getPlayer(guildId);
if (player) { if (player) {
await action(player); await action(player);
wlog.log(`L'utilisateur '${socketUser.identity.username}' effectue l'action '${actionName}' sur le player de la guilde : ${guildId}`); wlog.log(`L'utilisateur '${socketUser.identity.username}' effectue l'action '${actionName}' sur le player de la guilde : ${guildId}`);
IOAnswer(actionName, true); IOAnswer(actionName, true);
} else { } else {
wlog.warn(`Le player de la guilde : ${guildId} n'existe pas`); wlog.warn(`Le player de la guilde : ${guildId} n'existe pas`);
IOAnswer(actionName, false); IOAnswer(actionName, false);
} }
} }
} }
@@ -683,13 +742,12 @@ function init() {
wlog.step.end("server_init") wlog.step.end("server_init")
}) })
function AdminRequest(GRname, GRvalue) {
io.to("ADMIN").emit("ALWAYS/" + GRname, GRvalue)
}
function addGuildConnectedUser(user, guilds) { function addGuildConnectedUser(user, guilds) {
// Check if guilds is iterable
if(!guilds || !guilds[Symbol.iterator]) {
wlog.warn("Les guilds ne sont pas itérables")
return
}
for(var guild of guilds) { for(var guild of guilds) {
if(!guildConnectedUsers.has(guild)) { if(!guildConnectedUsers.has(guild)) {
guildConnectedUsers.set(guild.id, new Array()) guildConnectedUsers.set(guild.id, new Array())

View File

@@ -169,59 +169,46 @@ async function refreshAllUserInformation() {
await loadUsers(); await loadUsers();
clog.log("Récupération des informations de tous les utilisateurs..."); clog.log("Récupération des informations de tous les utilisateurs...");
for (const user of userList) { for (const user of userList) {
await refreshUserInformation(user.identity.id); await updateCredientials(user.identity.id);
} }
saveUsers(); saveUsers();
} }
async function refreshUserInformation(id) { async function updateCredientials(id) {
const user = getUserById(id); const user = getUserById(id);
if (!user) { if (!user) {
clog.warn(`Utilisateur ${id} non trouvé.`); clog.warn(`Utilisateur ${id} non trouvé.`);
return null; return null;
} }
clog.log(`Récupération (Refresh) des informations de l'utilisateur ${user.identity.username} (${user.identity.id})...`); clog.log(`Mise à jour des informations d'authentification Discord de l'utilisateur ${user.identity.username} (${user.identity.id})...`);
if (user.auth) { if (user.auth) {
const refresh_token = user.auth.refresh_token; // Check if the token is expired
const authCredientials = await discordAuth.refreshToken(refresh_token); const auth = await discordAuth.refreshToken(user.auth.refresh_token);
if(authCredientials) { if (auth) {
user.auth = authCredientials; // Check Rate limit by checking if auth.message exists
const guilds = await discordAuth.getUserGuilds(authCredientials); if(typeof auth.message !== "undefined") {
const identity = await discordAuth.getUserIdentity(authCredientials); clog.warn(`Erreur lors de la mise à jour des informations d'authentification de l'utilisateur ${user.identity.username} (${user.identity.id}) : ${auth.message}`);
if(identity) { return null;
user.identity = identity;
clog.log(`Récupération réussie des informations de l'utilisateur ${user.identity.username} (${user.identity.id})`);
}
else {
clog.warn(`Erreur lors de la récupération des informations de l'utilisateur ${user.identity.username} (${user.identity.id})`);
}
if(guilds) {
user.guilds = guilds;
clog.log(`Récupération réussie des guildes de l'utilisateur ${user.identity.username} (${user.identity.id})`);
}
else {
clog.warn(`Erreur lors de la récupération des guildes de l'utilisateur ${user.identity.username} (${user.identity.id})`);
}
// Update the user in the list
const userInUserList = userList.find(u => u.identity.id === user.identity.id);
if (userInUserList) {
userInUserList.auth = user.auth;
userInUserList.guilds = user.guilds;
} }
user.auth = auth;
clog.log(`Mise à jour réussie des informations d'authentification de l'utilisateur ${user.identity.username} (${user.identity.id})`);
} else { } else {
clog.warn(`Erreur lors de la récupération du token d'accès pour l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.warn(`Erreur lors de la mise à jour des informations d'authentification de l'utilisateur ${user.identity.username} (${user.identity.id})`);
// Delete tokens to oblige the user to reauthenticate
// Clear auth
user.destroyAuth();
return null;
} }
} else { // Update the user in the list
const userInUserList = userList.find(u => u.identity.id === user.identity.id);
if (userInUserList) {
userInUserList.auth = user.auth;
}
}
else {
clog.warn(`Aucune authentification trouvée pour l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.warn(`Aucune authentification trouvée pour l'utilisateur ${user.identity.username} (${user.identity.id})`);
} }
saveUsers();
return user.auth;
} }
async function updateGuilds(id) { async function updateGuilds(id) {
const user = getUserById(id); const user = getUserById(id);
if (!user) { if (!user) {
@@ -232,11 +219,16 @@ async function updateGuilds(id) {
if (user.auth) { if (user.auth) {
const guilds = await discordAuth.getUserGuilds(user.auth); const guilds = await discordAuth.getUserGuilds(user.auth);
if(guilds) { if(guilds) {
if(typeof guilds.message !== "undefined") {
clog.warn(`Erreur lors de la mise à jour des guildes de l'utilisateur ${user.identity.username} (${user.identity.id}) : ${guilds.message}`);
return null;
}
user.guilds = guilds; user.guilds = guilds;
clog.log(`Mise à jour réussie des guildes de l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.log(`Mise à jour réussie des guildes de l'utilisateur ${user.identity.username} (${user.identity.id})`);
} }
else { else {
clog.warn(`Erreur lors de la mise à jour des guildes de l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.warn(`Erreur lors de la mise à jour des guildes de l'utilisateur ${user.identity.username} (${user.identity.id})`);
return null;
} }
// Update the user in the list // Update the user in the list
const userInUserList = userList.find(u => u.identity.id === user.identity.id); const userInUserList = userList.find(u => u.identity.id === user.identity.id);
@@ -246,6 +238,7 @@ async function updateGuilds(id) {
} }
} else { } else {
clog.warn(`Aucune authentification trouvée pour l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.warn(`Aucune authentification trouvée pour l'utilisateur ${user.identity.username} (${user.identity.id})`);
return null;
} }
saveUsers(); saveUsers();
return user.guilds; return user.guilds;
@@ -261,11 +254,17 @@ async function updateIdentity(id) {
if (user.auth) { if (user.auth) {
const identity = await discordAuth.getUserIdentity(user.auth); const identity = await discordAuth.getUserIdentity(user.auth);
if(identity) { if(identity) {
// Check Rate limit by checking if identity.message exists
if(typeof identity.message !== "undefined") {
clog.warn(`Erreur lors de la mise à jour de l'identité de l'utilisateur ${user.identity.username} (${user.identity.id}) : ${identity.message}`);
return null;
}
user.identity = identity; user.identity = identity;
clog.log(`Mise à jour réussie de l'identité de l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.log(`Mise à jour réussie de l'identité de l'utilisateur ${user.identity.username} (${user.identity.id})`);
} }
else { else {
clog.warn(`Erreur lors de la mise à jour de l'identité de l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.warn(`Erreur lors de la mise à jour de l'identité de l'utilisateur ${user.identity.username} (${user.identity.id})`);
return null
} }
// Update the user in the list // Update the user in the list
const userInUserList = userList.find(u => u.identity.id === user.identity.id); const userInUserList = userList.find(u => u.identity.id === user.identity.id);
@@ -275,6 +274,7 @@ async function updateIdentity(id) {
} }
} else { } else {
clog.warn(`Aucune authentification trouvée pour l'utilisateur ${user.identity.username} (${user.identity.id})`); clog.warn(`Aucune authentification trouvée pour l'utilisateur ${user.identity.username} (${user.identity.id})`);
return null;
} }
saveUsers(); saveUsers();
return user.identity; return user.identity;
@@ -525,7 +525,7 @@ module.exports = {
removeToken, removeToken,
getSimpleUsers, getSimpleUsers,
getSimpleUser, getSimpleUser,
refreshUserInformation, updateCredientials,
refreshAllUserInformation, refreshAllUserInformation,
updateGuilds, updateGuilds,
updateIdentity updateIdentity