Version 1.1.0 - Refactor + Intergration Backend

This commit is contained in:
2025-07-25 17:56:30 +02:00
parent a59d7a66db
commit 98cdae97c0
58 changed files with 244 additions and 70 deletions

View File

@@ -0,0 +1,39 @@
const { Command } = require('../Command');
const { Embed } = require('../Embed');
const { __glob } = require("../../utils/GlobalVars");
const packageJson = require(__glob.PACKAGEINFO);
const command = new Command("about", "Affiche des informations sur le bot", (client, interaction) => {
const uptime = process.uptime();
const hours = Math.floor(uptime / 3600);
const minutes = Math.floor((uptime % 3600) / 60);
const seconds = Math.floor(uptime % 60);
const embed = new Embed(interaction)
embed.setColor(237, 12, 91)
embed.setThumbnail("https://cdn.discordapp.com/avatars/" + client.user.id + "/" + client.user.avatar + ".png")
embed.setTitle('Subsonics - Chopin')
embed.addField('Informations',"")
embed.addField('Version', packageJson.version + " ", true)
embed.addField('Uptime', `${hours}h ${minutes}m ${seconds}s `, true)
embed.addField("Ping", `${client.ws.ping} ms `, true)
embed.addField("Réalisé par", "Raphix - 2025", true)
embed.addColumn()
embed.addField('Versions :',"")
embed.addField('Node.js', process.version,true)
embed.addField('Discord.js', packageJson.dependencies["discord.js"].replace("^", ""),true)
embed.addColumn()
embed.addField('Webmetrik', packageJson.dependencies["webmetrik"].replace("^", ""),true)
embed.addField('Loguix', packageJson.dependencies["loguix"].replace("^", ""),true)
embed.addColumn()
embed.addField('FFmpeg', packageJson.dependencies["ffmpeg-static"].replace("^", ""),true)
embed.addField('Ytdl', packageJson.dependencies["@distube/ytdl-core"].replace("^", ""),true)
embed.addColumn()
embed.send()
})
module.exports = {command}

View File

@@ -0,0 +1,34 @@
const { Command } = require('../Command');
const { Embed } = require('../Embed');
const command = new Command("help", "Affiche la liste des commandes", (client, interaction) => {
const embed = new Embed(interaction)
embed.setColor(0x03ff2d)
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.addField('**Liste des commandes :**',"")
client.commands.forEach(command => {
let CommandName = command.data.name
if (command.data.options) {
command.data.options.forEach(option => {
if (option.choices) {
let choices = []
option.choices.forEach(choice => {
choices.push(choice.name)
})
CommandName += " <" + choices.join(" | ") +">"
}
})
}
embed.addField("/" + CommandName, command.data.description)
})
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.send()
})
module.exports = {command}

View File

@@ -0,0 +1,20 @@
const {Command } = require("../Command")
const {Embed, EmbedError} = require("../Embed")
const {Button} = require("../Button")
const command = new Command("invite", "Invite moi sur d'autres serveurs", (client, interaction) => {
const embed = new Embed(interaction)
embed.setColor(0xFF007F)
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.addBotPicture(client)
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.send()
})
module.exports = {command}

View File

@@ -0,0 +1,34 @@
const {Command} = require("../Command")
const {Embed, EmbedError} = require("../Embed")
const {Player, AllPlayers} = require("../../player/Player")
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 !", interaction)
const channel = interaction.member.voice.channel
var embed = new Embed(interaction)
if(AllPlayers.has(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()
embed.setColor(200, 20, 20)
embed.setTitle('**Déconnexion**')
embed.setDescription('Déconnexion du salon vocal')
embed.setThumbnail("https://www.iconsdb.com/icons/download/white/phone-51-64.png")
embed.send()
} else {
embed.returnError("Le bot n'est pas connecté à ce salon vocal")
}
})
module.exports = {command}

View File

@@ -0,0 +1,55 @@
const {Command} = require('../Command');
const {Embed, EmbedError} = require('../Embed');
const { Player } = require('../../player/Player');
const { Song } = require('../../player/Song');
const history = require('../../playlists/History');
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 !", interaction, true)
const media = interaction.options.get("media")
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 !", interaction)
const embed = new Embed(interaction)
embed.setColor(0x15e6ed)
const channel = interaction.member.voice.channel
const song = new Song()
await song.processMedia(media, interaction.user.username)
const player = new Player(channel.guildId)
player.join(channel)
if(now) {
player.play(song)
embed.setTitle('**Lecture immédiate**')
} else {
player.add(song)
embed.setTitle('**Ajout à liste de lecture**')
}
history.addToPersonalHistory(interaction.user.id, song)
embed.setDescription('**Titre : **' + song.title)
embed.addField('**Durée : **', song.readduration)
embed.addField("**Artiste : **",song.author)
embed.addField('**Demandé par **' + interaction.member.user.username, "")
embed.setThumbnail(song.thumbnail)
embed.send()
}, [{type: "FILE", name: "media", description: "Fichier audio à lire", required: true},
{type:"BOOLEAN", name: "now", description: "Lire le média maintenant", required: false}]
)
module.exports = {command}

View File

@@ -0,0 +1,44 @@
const {Command} = require("../Command")
const {Embed, EmbedError} = require("../Embed")
const { Player } = require("../../player/Player")
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 !", interaction)
const channel = interaction.member.voice.channel
const player = new Player(channel.guildId)
const result = player.pause()
var embed = new Embed(interaction)
embed.setColor(0x03ff2d)
result.then((pause) => {
if(pause == "no_music") {
embed.returnError("Il n'y a pas de musique en cours de lecture")
} else if(pause) {
embed.setTitle('Musique en pause')
embed.setDescription("La musique a été mise en pause")
embed.setThumbnail("https://www.iconsdb.com/icons/download/white/pause-64.png")
} else {
embed.setTitle('Musique reprise')
embed.setDescription("La musique a été reprise")
embed.setThumbnail("https://www.iconsdb.com/icons/download/white/play-64.png")
}
embed.send()
})
// Réponse en embed
})
module.exports = {command}

View File

@@ -0,0 +1,93 @@
const { Command } = require("../Command");
const { Embed, EmbedError } = require("../Embed");
const { Player } = require("../../player/Player");
const Finder = require("../../player/Finder");
const { Playlist } = require("../../playlists/Playlist");
const spotify = require("../../media/SpotifyInformation");
const history = require("../../playlists/History");
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 !", interaction)
const url = interaction.options.get("url")
const channel = interaction.member.voice.channel
const now = interaction.options.getBoolean("now") || false
const embed = new Embed(interaction)
await Finder.search(url.value).then(async (song) => {
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)
player.join(channel)
embed.setColor(0x15e6ed)
// Check if song is playlist
if(song instanceof Playlist) {
embed.setDescription('**Playlist : **' + song.songs.length + ' musiques')
embed.addField('**Titre : **' + song.title, "")
embed.addField('**Demandé par : **', interaction.member.user.username,)
embed.addField('**Auteur : **', song.author)
embed.addField('**Provient de : **', song.type.replace(/^\w/, (c) => c.toUpperCase()))
if(!song.type == "spotify") {
embed.addField('**Durée : **', song.readduration)
}
embed.addField('**Lien : **', song.url)
embed.addField(":warning: La récupération des musiques peut prendre du temps", "Veuillez patienter ... et éviter de lancer d'autres commandes")
embed.setThumbnail(song.thumbnail)
} else {
embed.setDescription('**Titre : **' + song.title)
embed.addField('**Durée : **', song.readduration)
embed.addField("**Artiste : **",song.author)
embed.addField('**Demandé par **' + interaction.member.user.username, "")
embed.addField("**Lien :** ", song.url)
embed.setThumbnail(song.thumbnail)
}
if(now) {
embed.setTitle("Lecture immédiate")
} else {
embed.setTitle("Ajoutée à la file d'attente")
}
embed.send()
if(song instanceof Playlist) {
if(song.type == "spotify") {
song = await spotify.getTracks(song)
}
player.readPlaylist(song, now)
} else {
if(now) {
player.play(song)
} else {
player.add(song)
}
history.addToPersonalHistory(interaction.user.id, song)
}
})
}, [{type: "STRING", name: "url", description: "Recherche / Lien audio (Youtube / Soundclound / Spotify)", required: true},
{type:"BOOLEAN", name: "now", description: "Lire le média maintenant", required: false}]
)
module.exports = {command}

View File

@@ -0,0 +1,51 @@
const {Command} = require("../Command")
const {Embed, EmbedError} = require("../Embed")
const { Player, AllPlayers } = require("../../player/Player")
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 !", interaction)
const channel = interaction.member.voice.channel
var embed = new Embed(interaction)
if(AllPlayers.has(channel.guildId)) {
const player = new Player(channel.guildId)
const result = player.previous()
embed.setColor(0x15e6ed)
result.then((song) => {
if(song == "no_music") {
embed.returnError("Il n'y a pas de musique précédemment jouée")
} else if(song) {
// Result is a song
embed.setTitle('**Musique précédente !**')
embed.setDescription('**Titre : **' + song.title)
embed.addField('**Durée : **'+ song.readduration, "")
embed.addField("**Artiste : **" + song.author, "")
embed.setThumbnail(song.thumbnail)
embed.send()
}
})
} else {
return embed.returnError("Le bot n'est pas connecté", interaction)
}
})
module.exports = {command}

View File

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

View File

@@ -0,0 +1,36 @@
const { Command } = require('../Command');
const { Embed } = require('../Embed');
const { Report } = require('../ReportSender');
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 result = report.send()
const embed = new Embed(interaction)
result.then((res) => {
if(!res) {
embed.setColor(0xc20f02)
embed.setTitle('Erreur')
embed.setDescription("Une erreur est survenue lors de l'envoi du rapport")
} else {
embed.setColor(0x00ff66)
embed.setTitle('Rapport envoyé')
embed.setDescription("Votre rapport a bien été envoyé !")
}
embed.send()
})
},
[{type: "CHOICES", name: "type", description: "Type", required: true, choices:
[{name: "Bug", value: "bug"},
{name: "Suggestion", value: "sugguestion"}],
},
{type: "STRING", name: "description", description: "Description du problème", required: true}]
)
module.exports = {command}

View File

@@ -0,0 +1,27 @@
const {Embed} = require("../Embed")
const {Command} = require("../Command")
const {restart} = require("../../utils/Maintenance")
const users = require("../../server/auth/User")
// Nécéssite une raison pour redémarrer le bot
const command = new Command("restart", "Redémarre le bot", (client, interaction) => {
// Check if user is admin from users list
const user = users.getUserById(interaction.user.id)
if(!user || !user.isAdmin()) {
interaction.reply({content: "Vous n'êtes pas admin", ephemeral: true})
return
}
const reason = interaction.options.getString("reason")
restart(reason)
const embed = new Embed(interaction)
embed.setColor(150, 20, 20)
embed.setTitle('Redémarrage')
embed.setDescription("Veuillez patientez, le bot va redémarrer dans un instant ! :arrows_counterclockwise:")
embed.addField('Raison', reason)
embed.send()
},
[{type: "STRING", name: "reason", description: "Raison du redémarrage", required: true}]
)
module.exports = {command}

View File

@@ -0,0 +1,48 @@
const {Command} = require("../Command")
const {Embed, EmbedError} = require("../Embed")
const { Player, AllPlayers } = require("../../player/Player")
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 !", interaction)
const channel = interaction.member.voice.channel
var embed = new Embed(interaction)
if(AllPlayers.has(channel.guildId)) {
const player = new Player(channel.guildId)
const result = player.skip()
embed.setColor(0x15e6ed)
result.then((song) => {
if(song == "no_music") {
embed.returnError("Il n'y a pas de musique en file d'attente", interaction)
} else if(song) {
// Result is a song
embed.setColor(0x15e6ed)
embed.setTitle('**Musique suivante !**')
embed.setDescription('**Titre : **' + song.title)
embed.addField('**Durée : **'+ song.readduration, "")
embed.addField("**Artiste : **" + song.author, "")
embed.setThumbnail(song.thumbnail)
}
embed.send()
})
} else {
return embed.returnError("Le bot n'est pas connecté", interaction)
}
})
module.exports = {command}

View File

@@ -0,0 +1,34 @@
const {Command} = require("../Command")
const {Embed, EmbedError} = require("../Embed")
const {Player} = require("../../player/Player")
const command = new Command("state", "Affiche la musique en cours", (client, interaction) => {
const channel = interaction.member.voice.channel
const player = new Player(channel.guildId)
const song = player.queue.getCurrent()
if(!song) {
var embed = new EmbedError("Il n'y a pas de musique en cours de lecture", interaction)
} else if(song) {
var embed = new Embed(interaction)
// Result is a song
embed.setColor(0x15e6ed)
embed.setTitle('**Musique en cours :**')
embed.setDescription('**Titre : **' + song.title)
embed.addField('**Durée : **', song.readduration)
embed.addField("**Artiste : **", song.author)
embed.setThumbnail(song.thumbnail)
embed.send()
}
})
module.exports = {command}

View File

@@ -0,0 +1,20 @@
const { Command } = require('../Command');
const { Button } = require('../Button');
const { Embed } = require('../Embed');
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 embed = new Embed(interaction)
embed.setColor(0xffffff)
embed.setTitle('Subsonics - Chopin')
embed.addBotPicture(client)
embed.setDescription('Vous pouvez contrôler le bot depuis le site web ! \n Nécéssite une connexion avec votre compte Discord.')
const linkButton = new Button("Site web", null, 5, config.getWebsiteLink())
embed.addButton(linkButton)
embed.send()
})
module.exports = {command}