Compare commits
24 Commits
e313d4228c
...
main
Author | SHA1 | Date | |
---|---|---|---|
96cd60912b
|
|||
b2aadc7c3c
|
|||
dcc056455e
|
|||
f777fb821a
|
|||
ecbda838d3
|
|||
5ac195fd46
|
|||
914edbbf13
|
|||
c376e3259c
|
|||
f3b237b74f
|
|||
83e11f3341
|
|||
b132041d16
|
|||
33da8e8527
|
|||
c613d67c60
|
|||
48e5bfad60
|
|||
54fd731ab9
|
|||
5b8f591216
|
|||
2fe5d35efe
|
|||
b0f5ccbe5a
|
|||
98e5c41fa5
|
|||
f41eddf1dc
|
|||
f12bbe8ad2
|
|||
0c50874644
|
|||
59ea576181
|
|||
8b2728622c
|
86
.gitea/workflows/deploy.yml
Normal file
86
.gitea/workflows/deploy.yml
Normal file
@@ -0,0 +1,86 @@
|
|||||||
|
name: Deployment Pipeline
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
deploy:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Setup SSH
|
||||||
|
env:
|
||||||
|
SSH_PRIVATE_KEY: ${{ secrets.SSH_PRIVATE_KEY }}
|
||||||
|
run: |
|
||||||
|
mkdir -p ~/.ssh
|
||||||
|
echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa
|
||||||
|
chmod 600 ~/.ssh/id_rsa
|
||||||
|
eval "$(ssh-agent -s)"
|
||||||
|
ssh-add ~/.ssh/id_rsa
|
||||||
|
ssh-keyscan git.raphix.fr >> ~/.ssh/known_hosts
|
||||||
|
|
||||||
|
- name: Deploy Subsonics as gitlab-ci
|
||||||
|
run: |
|
||||||
|
ssh -A -o StrictHostKeyChecking=no raphix@alpha.raphix.fr << 'EOF'
|
||||||
|
sudo su - gitlab-ci -c '
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Variables PM2 et npm
|
||||||
|
export PM2_HOME=/home/gitlab-ci/.pm2
|
||||||
|
export NPM_CONFIG_CACHE=/home/gitlab-ci/.npm
|
||||||
|
|
||||||
|
mkdir -p $PM2_HOME $NPM_CONFIG_CACHE
|
||||||
|
chown -R gitlab-ci:gitlab-ci $PM2_HOME $NPM_CONFIG_CACHE
|
||||||
|
|
||||||
|
echo "[Subsonics-Deploy] - Stage - Déploiement - START"
|
||||||
|
|
||||||
|
echo "[Subsonics-Deploy] - Arrêt de Subsonics : Processing"
|
||||||
|
cd /home/gitlab-ci
|
||||||
|
pm2 stop "Subsonics - Backend" || true
|
||||||
|
pm2 delete "Subsonics - Backend" || true
|
||||||
|
echo "[Subsonics-Deploy] - Arrêt de Subsonics : Success"
|
||||||
|
|
||||||
|
# Préparer tempdata
|
||||||
|
if [ ! -d "/home/gitlab-ci/backend/data" ]; then
|
||||||
|
mkdir -p /home/gitlab-ci/backend/data
|
||||||
|
fi
|
||||||
|
mv /home/gitlab-ci/backend/data/ /home/gitlab-ci/tempdata || true
|
||||||
|
|
||||||
|
echo "[Subsonics-Deploy] - Suppression de Subsonics : Processing"
|
||||||
|
rm -rf ./backend
|
||||||
|
echo "[Subsonics-Deploy] - Suppression de Subsonics : Success"
|
||||||
|
|
||||||
|
echo "[Subsonics-Deploy] - Installation de Subsonics : Processing"
|
||||||
|
git clone https://git.raphix.fr/subsonics/chopin backend
|
||||||
|
echo "[Subsonics-Deploy] - Installation de Subsonics : Success"
|
||||||
|
|
||||||
|
echo "[Subsonics-Deploy] - Installation des dépendances : Processing"
|
||||||
|
cd /home/gitlab-ci/backend
|
||||||
|
|
||||||
|
# Nettoyage node_modules et tempdata
|
||||||
|
rm -rf node_modules
|
||||||
|
if [ -d "/home/gitlab-ci/tempdata" ]; then
|
||||||
|
mv /home/gitlab-ci/tempdata/ ./data
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Assurer la propriété gitlab-ci
|
||||||
|
chown -R gitlab-ci:gitlab-ci /home/gitlab-ci/backend
|
||||||
|
mkdir -p $NPM_CONFIG_CACHE
|
||||||
|
chown -R gitlab-ci:gitlab-ci $NPM_CONFIG_CACHE
|
||||||
|
|
||||||
|
npm install --omit=dev
|
||||||
|
echo "[Subsonics-Deploy] - Installation des dépendances : Success"
|
||||||
|
|
||||||
|
echo "[Subsonics-Deploy] - Démarrage de Subsonics : Processing"
|
||||||
|
cd /home/gitlab-ci
|
||||||
|
pm2 start subsonic.config.js
|
||||||
|
echo "[Subsonics-Deploy] - Démarrage de Subsonics : Success"
|
||||||
|
|
||||||
|
echo "[Subsonics-Deploy] - Stage - Déploiement - END"
|
||||||
|
'
|
||||||
|
EOF
|
29
CHANGELOG.html
Normal file
29
CHANGELOG.html
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
<div class="changelog-version changelog-actual">
|
||||||
|
<h2>Chopin - Version /*1.2.0*/</h2>
|
||||||
|
<p class="changelog-date">*_Date de sortie_*: *-07/09/2025-*</p>
|
||||||
|
<ul>
|
||||||
|
<li>/#[AJOUT][FRONTEND]#/ Suggestion de recherche, depuis Youtube</li>
|
||||||
|
<li>/#[FIX][FRONTEND]#/ Optimisation des bouttons, avec une modification du composant</li>
|
||||||
|
<li>/#[AJOUT][DISCORD]#/ Ajout de la sécurité, permettant de restreindre l'utilisation du Bot au Rôle paramétré</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="changelog-version">
|
||||||
|
<h2>Chopin - Version /*1.1.0*/</h2>
|
||||||
|
<p class="changelog-date">*_Date de sortie_*: *-06/09/2025-*</p>
|
||||||
|
<ul>
|
||||||
|
<li>/#[AJOUT][FRONTEND]#/ Désormais, lorsque l'utilisateur n'est pas connecté, les bouttons de lecture sont désactivés au lieu d'être masqués</li>
|
||||||
|
<li>/#[AJOUT][FRONTEND] #/ Ajout de la prise en charge de plusieurs fichiers en même temps (Impossibilité sur Discord à cause de restriction) !</li>
|
||||||
|
<li>/#[FIX][BACKEND]#/ La source Youtube est désormais fonctionnelle</li>
|
||||||
|
<li>/#[FIX][BACKEND]#/ Le changement de channel est désormais fonctionnel.</li>
|
||||||
|
<li>/#[FIX][FRONTEND]#/ Résolution d'un problème d'affichage du changelog et de la liste de lecture</li>
|
||||||
|
<li>/#[FIX][FRONTEND]#/ Le "En ligne" est désormais resynchronisé sur le Bot</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="changelog-version">
|
||||||
|
<h2>Chopin - Version /*1.0.0*/</h2>
|
||||||
|
<p class="changelog-date">*_Date de sortie_*: *-29/08/2025-*</p>
|
||||||
|
<ul>
|
||||||
|
<li>/#[FRONTEND]#/ Sortie de la version 1.0.0 de Chopin, le bot Discord pour SubSonics. Refonte graphique et passage sur Vue JS</li>
|
||||||
|
<li>/#[BACKEND]#/ Refonte de toute la gestion de la musique et ajout de nouvelles fonctionnalités</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
2210
package-lock.json
generated
2210
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "chopin-backend",
|
"name": "chopin-backend",
|
||||||
"version": "1.1.1",
|
"version": "1.2.0",
|
||||||
"description": "Discord Bot for music - Fetching everywhere !",
|
"description": "Discord Bot for music - Fetching everywhere !",
|
||||||
"main": "src/main.js",
|
"main": "src/main.js",
|
||||||
"nodemonConfig": {
|
"nodemonConfig": {
|
||||||
@@ -21,12 +21,10 @@
|
|||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@discordjs/voice": "^0.18.0",
|
"@discordjs/voice": "^0.18.0",
|
||||||
"@distube/ytdl-core": "^4.16.10",
|
"@distube/ytdl-core": "^4.16.12",
|
||||||
"@distube/ytsr": "2.0.4",
|
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"discord-player": "^7.1.0",
|
"discord-player": "^7.1.0",
|
||||||
"discord.js": "^14.18.0",
|
"discord.js": "^14.18.0",
|
||||||
"express": "^4.21.2",
|
|
||||||
"ffmpeg-static": "^5.2.0",
|
"ffmpeg-static": "^5.2.0",
|
||||||
"ffprobe": "^1.1.2",
|
"ffprobe": "^1.1.2",
|
||||||
"ffprobe-static": "^3.1.0",
|
"ffprobe-static": "^3.1.0",
|
||||||
@@ -42,6 +40,7 @@
|
|||||||
"spotify-web-api-node": "^5.0.2",
|
"spotify-web-api-node": "^5.0.2",
|
||||||
"uuid": "^11.1.0",
|
"uuid": "^11.1.0",
|
||||||
"webmetrik": "^0.1.4",
|
"webmetrik": "^0.1.4",
|
||||||
|
"yt-search": "^2.13.1",
|
||||||
"ytfps": "^1.2.0"
|
"ytfps": "^1.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -7,6 +7,8 @@ const config = require("../utils/Database/Configuration")
|
|||||||
const metric = require("webmetrik")
|
const metric = require("webmetrik")
|
||||||
const { Player } = require("../player/Player")
|
const { Player } = require("../player/Player")
|
||||||
const {refreshAllUserInformation} = require("../server/auth/User")
|
const {refreshAllUserInformation} = require("../server/auth/User")
|
||||||
|
const serverSettings = require("./ServerSettings")
|
||||||
|
const { Embed, EmbedError } = require("./Embed")
|
||||||
|
|
||||||
const dlog = new LogType("Discord")
|
const dlog = new LogType("Discord")
|
||||||
const glog = new LogType("GuildUpdater")
|
const glog = new LogType("GuildUpdater")
|
||||||
@@ -49,6 +51,29 @@ function getGuildMembers(guildId) {
|
|||||||
return guild.members.cache.map(member => member.user.id)
|
return guild.members.cache.map(member => member.user.id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getGuildMember(guildId, memberId) {
|
||||||
|
const guild = client.guilds.cache.get(guildId)
|
||||||
|
if(!guild) {
|
||||||
|
dlog.error("Guild not found: " + guildId)
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return guild.members.cache.get(memberId) || null
|
||||||
|
}
|
||||||
|
|
||||||
|
function getGuildRoles(guildId) {
|
||||||
|
const guild = client.guilds.cache.get(guildId)
|
||||||
|
if(!guild) {
|
||||||
|
dlog.error("Guild not found: " + guildId)
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
return guild.roles.cache.map(role => ({
|
||||||
|
id: role.id,
|
||||||
|
name: role.name,
|
||||||
|
color: role.color,
|
||||||
|
position: role.position
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
function getChannel(guildId, channelId) {
|
function getChannel(guildId, channelId) {
|
||||||
return client.guilds.cache.get(guildId).channels.cache.get(channelId)
|
return client.guilds.cache.get(guildId).channels.cache.get(channelId)
|
||||||
}
|
}
|
||||||
@@ -77,22 +102,37 @@ function init() {
|
|||||||
operational = true
|
operational = true
|
||||||
})
|
})
|
||||||
|
|
||||||
client.on("interactionCreate", (interaction) => {
|
client.on("interactionCreate", async (interaction) => {
|
||||||
|
|
||||||
if(!interaction.isCommand()) return;
|
if(!interaction.isCommand()) return;
|
||||||
|
|
||||||
var numberOfCommands = new metric.Metric("numberOfCommands", "Nombre de commandes éxécutées")
|
var numberOfCommands = new metric.Metric("numberOfCommands", "Nombre de commandes éxécutées")
|
||||||
numberOfCommands.setValue(numberOfCommands.getValue() + 1)
|
numberOfCommands.setValue(numberOfCommands.getValue() + 1)
|
||||||
|
var numberOfCommandsServer = new metric.Metric("numberOfCommands_" + interaction.guild.id, "Nombre de commandes éxécutées sur le serveur : " + interaction.guild.name)
|
||||||
|
numberOfCommandsServer.setValue(numberOfCommandsServer.getValue() + 1)
|
||||||
|
|
||||||
const command = client.commands.get(interaction.commandName)
|
const command = client.commands.get(interaction.commandName)
|
||||||
|
const roleProtected = await serverSettings.getSecureRole(interaction.guild.id) || false
|
||||||
|
var havePermission = true;
|
||||||
|
if(roleProtected) {
|
||||||
|
await interaction.member.fetch()
|
||||||
|
if(!interaction.member.roles.cache.has(roleProtected.id)) {
|
||||||
|
havePermission = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// Create a metric to count the number of commands executed by each user
|
// Create a metric to count the number of commands executed by each user
|
||||||
const userCommand = new metric.Metric("userCommand_" + interaction.member.user.username, "Nombre de commandes éxécutées par l'utilisateur : " + interaction.member.user.username)
|
const userCommand = new metric.Metric("userCommand_" + interaction.member.user.username, "Nombre de commandes éxécutées par l'utilisateur : " + interaction.member.user.username)
|
||||||
userCommand.setValue(userCommand.getValue() + 1)
|
userCommand.setValue(userCommand.getValue() + 1)
|
||||||
dlog.log(interaction.member.user.username + "-> /" + interaction.commandName)
|
dlog.log(interaction.member.user.username + "-> /" + interaction.commandName)
|
||||||
command.execute(client, interaction)
|
if(havePermission) {
|
||||||
|
command.execute(client, interaction)
|
||||||
|
} else {
|
||||||
|
const embed = new EmbedError(`L'utilisation du Bot est réservée aux membres ayant le rôle "${roleProtected.name}"`, interaction, true)
|
||||||
|
embed.setTitle("Accès refusé")
|
||||||
|
embed.send()
|
||||||
|
}
|
||||||
} catch(error) {
|
} catch(error) {
|
||||||
|
|
||||||
dlog.error(interaction.member.user.username + "-> /" + interaction.commandName + " : ERREUR RENCONTRE")
|
dlog.error(interaction.member.user.username + "-> /" + interaction.commandName + " : ERREUR RENCONTRE")
|
||||||
@@ -169,7 +209,7 @@ function init() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
process.emit("VOCAL_UPDATE")
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -209,23 +249,15 @@ async function refreshGuilds() {
|
|||||||
|
|
||||||
function checkRequiredPermission(guildMember) {
|
function checkRequiredPermission(guildMember) {
|
||||||
const requiredPermissions = [
|
const requiredPermissions = [
|
||||||
'CreateInstantInvite', 'AddReactions',
|
'ViewChannel', // Voir les salons
|
||||||
'Stream', 'ViewChannel',
|
'SendMessages', // Envoyer des messages texte
|
||||||
'SendMessages', 'SendTTSMessages',
|
'ReadMessageHistory', // Lire l’historique des messages
|
||||||
'EmbedLinks', 'AttachFiles',
|
'Connect', // Se connecter aux salons vocaux
|
||||||
'ReadMessageHistory', 'UseExternalEmojis',
|
'Speak' // Parler dans les salons vocaux
|
||||||
'Connect', 'Speak',
|
]
|
||||||
'UseVAD', 'ChangeNickname',
|
|
||||||
'UseApplicationCommands', 'RequestToSpeak',
|
|
||||||
'CreatePublicThreads', 'CreatePrivateThreads',
|
|
||||||
'UseExternalStickers', 'SendMessagesInThreads',
|
|
||||||
'UseEmbeddedActivities', 'UseSoundboard',
|
|
||||||
'UseExternalSounds', 'SendVoiceMessages',
|
|
||||||
'SendPolls', 'UseExternalApps'
|
|
||||||
]
|
|
||||||
return requiredPermissions.filter(permission => !guildMember.permissions.has(permission));
|
return requiredPermissions.filter(permission => !guildMember.permissions.has(permission));
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {init, getClient, getGuilds, getMembersVoices, getChannel, getGuildMembers, isReady}
|
module.exports = {init, getClient, getGuilds, getMembersVoices, getChannel, getGuildMembers, getGuildMember, isReady, getGuildRoles}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -4,6 +4,8 @@ const wlog = new LogType("MediaBase")
|
|||||||
const { Database } = require("../utils/Database/Database")
|
const { Database } = require("../utils/Database/Database")
|
||||||
const {__glob} = require("../utils/GlobalVars")
|
const {__glob} = require("../utils/GlobalVars")
|
||||||
const { AttachmentBuilder } = require("discord.js")
|
const { AttachmentBuilder } = require("discord.js")
|
||||||
|
const { Song } = require("../player/Song")
|
||||||
|
const { getMediaInformationFromUrl } = require("../media/MediaInformation")
|
||||||
const discordBot = require("./Bot")
|
const discordBot = require("./Bot")
|
||||||
|
|
||||||
|
|
||||||
@@ -54,7 +56,7 @@ discordBot.getClient().on("ready", () => {
|
|||||||
|
|
||||||
// SEND FILE TO DISCORD AND GET THE URL ID
|
// SEND FILE TO DISCORD AND GET THE URL ID
|
||||||
|
|
||||||
async function postMedia(file) {
|
async function postMedia(file, userId) {
|
||||||
if(!connected) {
|
if(!connected) {
|
||||||
wlog.error("La base de données multimédia n'est pas connectée, impossible d'envoyer le fichier.")
|
wlog.error("La base de données multimédia n'est pas connectée, impossible d'envoyer le fichier.")
|
||||||
return null
|
return null
|
||||||
@@ -73,7 +75,8 @@ async function postMedia(file) {
|
|||||||
url: url,
|
url: url,
|
||||||
name: file.name,
|
name: file.name,
|
||||||
size: file.size,
|
size: file.size,
|
||||||
createdAt: new Date().toISOString()
|
createdAt: new Date().toISOString(),
|
||||||
|
userId: userId
|
||||||
})
|
})
|
||||||
mediaDB.save()
|
mediaDB.save()
|
||||||
return url
|
return url
|
||||||
@@ -83,6 +86,33 @@ async function postMedia(file) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getAllMedia(userId) {
|
||||||
|
if(!connected) {
|
||||||
|
wlog.error("La base de données multimédia n'est pas connectée, impossible de récupérer les fichiers.")
|
||||||
|
return []
|
||||||
|
}
|
||||||
|
const allSongs = mediaDB.data.filter(m => m.userId === userId)
|
||||||
|
const songs = []
|
||||||
|
for(const songDB of allSongs) {
|
||||||
|
const song = new Song()
|
||||||
|
const information = await getMediaInformationFromUrl(song, songDB.url)
|
||||||
|
if(!information) {
|
||||||
|
mediaDB.data = mediaDB.data.filter(m => m.id !== songDB.id)
|
||||||
|
mediaDB.save()
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
song.type = "attachment"
|
||||||
|
song.author = songDB.author
|
||||||
|
song.createdAt = songDB.createdAt
|
||||||
|
song.author = songDB.userId
|
||||||
|
song.title = songDB.name
|
||||||
|
song.id = songDB.id
|
||||||
|
song.url = songDB.url
|
||||||
|
songs.push(song)
|
||||||
|
}
|
||||||
|
return songs
|
||||||
|
}
|
||||||
|
|
||||||
async function getMedia(id) {
|
async function getMedia(id) {
|
||||||
if(!connected) {
|
if(!connected) {
|
||||||
wlog.error("La base de données multimédia n'est pas connectée, impossible de récupérer le fichier.")
|
wlog.error("La base de données multimédia n'est pas connectée, impossible de récupérer le fichier.")
|
||||||
@@ -103,7 +133,26 @@ async function getMedia(id) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteMedia(data, userId) {
|
||||||
|
if(!connected) {
|
||||||
|
wlog.error("La base de données multimédia n'est pas connectée, impossible de supprimer le fichier.")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
const mediaIndex = mediaDB.data.findIndex(m => m.id === data.id && m.userId === userId)
|
||||||
|
if(mediaIndex === -1) {
|
||||||
|
wlog.error(`Aucun média trouvé avec l'ID : ${data.id} pour l'utilisateur : ${userId}`)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
mediaDB.data.splice(mediaIndex, 1)
|
||||||
|
mediaDB.save()
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
postMedia,
|
postMedia,
|
||||||
getMedia,
|
getMedia,
|
||||||
|
deleteMedia,
|
||||||
|
getAllMedia
|
||||||
}
|
}
|
38
src/discord/ServerSettings.js
Normal file
38
src/discord/ServerSettings.js
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
const { LogType } = require('loguix');
|
||||||
|
const clog = new LogType('ServerSettings');
|
||||||
|
const { __glob } = require('../utils/GlobalVars');
|
||||||
|
const { Database } = require('../utils/Database/Database');
|
||||||
|
const ServerDB = new Database("server_settings", __glob.SERVER_DB, {});
|
||||||
|
|
||||||
|
function getSecureRole(guildId) {
|
||||||
|
checkKey(guildId);
|
||||||
|
var role = ServerDB.getData()[guildId].secureRole || null;
|
||||||
|
if(role) {
|
||||||
|
if(role.name === "@everyone") {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return role;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setSecureRole(guildId, roleId) {
|
||||||
|
checkKey(guildId);
|
||||||
|
ServerDB.getData()[guildId].secureRole = roleId;
|
||||||
|
ServerDB.save();
|
||||||
|
process.emit("USERS_UPDATE")
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function checkKey(guildId) {
|
||||||
|
const data = ServerDB.getData();
|
||||||
|
if (!data[guildId]) {
|
||||||
|
data[guildId] = { secureRole: null };
|
||||||
|
ServerDB.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getSecureRole,
|
||||||
|
setSecureRole
|
||||||
|
};
|
@@ -10,8 +10,7 @@ require("loguix").setup(__glob.LOGS, __glob.PACKAGEINFO)
|
|||||||
const config = require("./utils/Database/Configuration")
|
const config = require("./utils/Database/Configuration")
|
||||||
const metric = require("webmetrik")
|
const metric = require("webmetrik")
|
||||||
metric.setMetricFile(__glob.METRIC_FILE)
|
metric.setMetricFile(__glob.METRIC_FILE)
|
||||||
metric.publishMetrics("8001", "raphraph")
|
metric.publishMetrics("8001", "subsonicsMetricsRaph")
|
||||||
|
|
||||||
|
|
||||||
// SETUP
|
// SETUP
|
||||||
|
|
||||||
|
@@ -21,7 +21,7 @@ async function getMediaInformation(instance, media, provider) {
|
|||||||
|
|
||||||
// Obtenir l'auteur (s'il existe)
|
// Obtenir l'auteur (s'il existe)
|
||||||
instance.author = info.streams?.[0]?.tags?.artist ?? instance.author;
|
instance.author = info.streams?.[0]?.tags?.artist ?? instance.author;
|
||||||
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
clog.error("Impossible de récupérer les informations de la musique : " + media.attachment.name)
|
clog.error("Impossible de récupérer les informations de la musique : " + media.attachment.name)
|
||||||
clog.error(err)
|
clog.error(err)
|
||||||
@@ -46,7 +46,7 @@ async function getMediaInformationFromUrl(instance, url) {
|
|||||||
|
|
||||||
// Obtenir l'auteur (s'il existe)
|
// Obtenir l'auteur (s'il existe)
|
||||||
instance.author = info.streams?.[0]?.tags?.artist ?? "Auteur inconnu";
|
instance.author = info.streams?.[0]?.tags?.artist ?? "Auteur inconnu";
|
||||||
|
return true;
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
clog.error("Impossible de récupérer les informations de la musique depuis l'URL : " + url);
|
clog.error("Impossible de récupérer les informations de la musique depuis l'URL : " + url);
|
||||||
console.log(err)
|
console.log(err)
|
||||||
|
@@ -3,7 +3,7 @@ const clog = new LogType("YoutubeInformation");
|
|||||||
const { Song } = require('../player/Song');
|
const { Song } = require('../player/Song');
|
||||||
const { Playlist } = require('../playlists/Playlist');
|
const { Playlist } = require('../playlists/Playlist');
|
||||||
const { getReadableDuration, getSecondsDuration } = require('../utils/TimeConverter');
|
const { getReadableDuration, getSecondsDuration } = require('../utils/TimeConverter');
|
||||||
const ytsr = require('@distube/ytsr');
|
const yts = require("yt-search")
|
||||||
const ytfps = require('ytfps');
|
const ytfps = require('ytfps');
|
||||||
|
|
||||||
async function getQuery(query, multiple) {
|
async function getQuery(query, multiple) {
|
||||||
@@ -14,15 +14,15 @@ async function getQuery(query, multiple) {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
const limit = multiple ? 25 : 1;
|
const limit = multiple ? 25 : 1;
|
||||||
const searchResults = await ytsr(query, { limit });
|
const searchResults = await yts({ query: query, limit: limit });
|
||||||
const videos = searchResults.items.filter(item => item.type === 'video');
|
const videos = searchResults.videos;
|
||||||
|
|
||||||
if (videos.length === 0) {
|
if (videos.length === 0) {
|
||||||
clog.error("Impossible de récupérer le lien de la vidéo YouTube à partir de la requête");
|
clog.error("Impossible de récupérer le lien de la vidéo YouTube à partir de la requête");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const songs = await Promise.all(videos.map(video => getVideo(video.url)));
|
const songs = await Promise.all(videos.map(video => new Song().processYoutubeVideo(video)));
|
||||||
return multiple ? songs.filter(song => song !== null) : songs[0];
|
return multiple ? songs.filter(song => song !== null) : songs[0];
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
clog.error('Erreur lors de la recherche YouTube: ' + error);
|
clog.error('Erreur lors de la recherche YouTube: ' + error);
|
||||||
@@ -38,9 +38,7 @@ async function getVideo(url) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const searchResults = await ytsr(videoId[1], { limit: 1 });
|
const video = await yts({videoId: videoId[1]});
|
||||||
const video = searchResults.items.find(item => item.type === 'video');
|
|
||||||
|
|
||||||
if (video) {
|
if (video) {
|
||||||
const songReturn = new Song();
|
const songReturn = new Song();
|
||||||
await songReturn.processYoutubeVideo(video);
|
await songReturn.processYoutubeVideo(video);
|
||||||
@@ -72,14 +70,14 @@ async function getPlaylist(url) {
|
|||||||
playlistId = url.match(/(list=)([a-zA-Z0-9_-]+)/);
|
playlistId = url.match(/(list=)([a-zA-Z0-9_-]+)/);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(playlistId);
|
|
||||||
|
|
||||||
if (playlistId === null) {
|
if (playlistId === null) {
|
||||||
clog.error("Impossible de récupérer l'identifiant de la playlist YouTube à partir de l'URL");
|
clog.error("Impossible de récupérer l'identifiant de la playlist YouTube à partir de l'URL");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const playlistInfo = await ytfps(playlistId[2]);
|
const playlistInfo = await yts({ listId: playlistId[2] });
|
||||||
|
|
||||||
if (!playlistInfo) {
|
if (!playlistInfo) {
|
||||||
clog.error("Impossible de récupérer la playlist YouTube à partir de l'identifiant");
|
clog.error("Impossible de récupérer la playlist YouTube à partir de l'identifiant");
|
||||||
@@ -90,15 +88,16 @@ async function getPlaylist(url) {
|
|||||||
playlist.type = "youtube";
|
playlist.type = "youtube";
|
||||||
playlist.author = playlistInfo.author.name;
|
playlist.author = playlistInfo.author.name;
|
||||||
playlist.authorId = playlistInfo.author.url;
|
playlist.authorId = playlistInfo.author.url;
|
||||||
|
playlist.authorAvatar = await getYouTubeProfilePicture(playlistInfo.author.url);
|
||||||
playlist.title = playlistInfo.title;
|
playlist.title = playlistInfo.title;
|
||||||
playlist.thumbnail = playlistInfo.thumbnail_url;
|
playlist.thumbnail = playlistInfo.thumbnail;
|
||||||
playlist.description = playlistInfo.description;
|
|
||||||
playlist.url = `https://www.youtube.com/playlist?list=${playlistId[2]}`;
|
playlist.url = `https://www.youtube.com/playlist?list=${playlistId[2]}`;
|
||||||
playlist.id = playlistId[2];
|
playlist.id = playlistInfo.listId;
|
||||||
|
playlist.views = playlistInfo.views;
|
||||||
|
|
||||||
for (const video of playlistInfo.videos) {
|
for (const video of playlistInfo.videos) {
|
||||||
const song = new Song();
|
const song = new Song();
|
||||||
await song.processYoutubeVideo(video, true);
|
await song.processYoutubeVideo(video);
|
||||||
playlist.duration += song.duration;
|
playlist.duration += song.duration;
|
||||||
playlist.songs.push(song);
|
playlist.songs.push(song);
|
||||||
}
|
}
|
||||||
@@ -117,11 +116,9 @@ async function getSecondsFromUrl(url) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
const searchResults = await ytsr(videoId[1], { limit: 1 });
|
const video = await yts({ videoId: videoId[1] });
|
||||||
const video = searchResults.items.find(item => item.type === 'video');
|
|
||||||
console.log(video);
|
|
||||||
if (video) {
|
if (video) {
|
||||||
return getSecondsDuration(video.duration); // Convert seconds to milliseconds
|
return video.duration.seconds;
|
||||||
} else {
|
} else {
|
||||||
clog.error("Impossible de récupérer la vidéo YouTube à partir de l'identifiant");
|
clog.error("Impossible de récupérer la vidéo YouTube à partir de l'identifiant");
|
||||||
return null;
|
return null;
|
||||||
@@ -132,4 +129,36 @@ async function getSecondsFromUrl(url) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function getYouTubeProfilePicture(channelUrl) {
|
||||||
|
try {
|
||||||
|
const res = await fetch(channelUrl, {
|
||||||
|
headers: {
|
||||||
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const html = await res.text();
|
||||||
|
|
||||||
|
// Match img with yt-spec-avatar-shape__image in class list
|
||||||
|
const imgRegex = /<img[^>]*(?:class="[^"]*\byt-spec-avatar-shape__image\b[^"]*"[^>]*|[^>]*class="[^"]*\byt-spec-avatar-shape__image\b[^"]*")[^>]*src="([^"]+)"/i;
|
||||||
|
const imgMatch = html.match(imgRegex);
|
||||||
|
|
||||||
|
if (imgMatch && imgMatch[1]) {
|
||||||
|
return imgMatch[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallback: look for avatar in embedded JSON
|
||||||
|
const jsonRegex = /"avatar":\{"thumbnails":\[\{"url":"(.*?)"/;
|
||||||
|
const match = html.match(jsonRegex);
|
||||||
|
if (match && match[1]) {
|
||||||
|
return match[1].replace(/\\u0026/g, "&"); // Decode \u0026 to &
|
||||||
|
}
|
||||||
|
|
||||||
|
console.warn("Photo non trouvée pour :", channelUrl);
|
||||||
|
return null;
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Erreur :", err);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = { getQuery, getVideo, getPlaylist, getSecondsFromUrl };
|
module.exports = { getQuery, getVideo, getPlaylist, getSecondsFromUrl };
|
||||||
|
@@ -60,6 +60,7 @@ class List {
|
|||||||
}
|
}
|
||||||
this.setCurrent(song)
|
this.setCurrent(song)
|
||||||
process.emit("PLAYERS_UPDATE")
|
process.emit("PLAYERS_UPDATE")
|
||||||
|
//TODO: Check History and continuity
|
||||||
return song
|
return song
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -2,19 +2,35 @@ const {createAudioResource, VoiceConnectionStatus, createAudioPlayer, StreamType
|
|||||||
const {LogType} = require('loguix')
|
const {LogType} = require('loguix')
|
||||||
const clog = new LogType("Youtube-Stream")
|
const clog = new LogType("Youtube-Stream")
|
||||||
const ytdl = require('@distube/ytdl-core')
|
const ytdl = require('@distube/ytdl-core')
|
||||||
const ffmpeg = require('fluent-ffmpeg')
|
const { __glob } = require('../../utils/GlobalVars');
|
||||||
const { getRandomIPv6 } = require("@distube/ytdl-core/lib/utils");
|
const fs = require('fs');
|
||||||
|
|
||||||
async function getStream(song) {
|
async function getStream(song) {
|
||||||
|
|
||||||
|
// FIXME: Change youtube provider
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
|
const headers = {
|
||||||
|
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) ' +
|
||||||
|
'AppleWebKit/537.36 (KHTML, like Gecko) ' +
|
||||||
|
'Chrome/116.0.5845.97 Safari/537.36',
|
||||||
|
'Accept-Language': 'en-US,en;q=0.9'
|
||||||
|
};
|
||||||
|
|
||||||
|
var cookies = await JSON.parse(await fs.readFileSync(__glob.COOKIES, 'utf-8'));
|
||||||
|
const proxy = await JSON.parse(await fs.readFileSync(__glob.PROXY, 'utf-8'));
|
||||||
|
const agent = ytdl.createProxyAgent(proxy, cookies)
|
||||||
let stream = ytdl(song.url, {
|
let stream = ytdl(song.url, {
|
||||||
quality: 'highestaudio',
|
quality: 'highestaudio',
|
||||||
highWaterMark: 1 << 30,
|
highWaterMark: 1 << 30,
|
||||||
liveBuffer: 20000,
|
liveBuffer: 20000,
|
||||||
dlChunkSize: 0,
|
dlChunkSize: 0,
|
||||||
bitrate: 128,
|
bitrate: 128,
|
||||||
|
requestOptions: {
|
||||||
|
headers: headers,
|
||||||
|
},
|
||||||
|
agent: agent,
|
||||||
});
|
});
|
||||||
|
|
||||||
return stream
|
return stream
|
||||||
|
@@ -5,6 +5,7 @@ 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');
|
||||||
|
const { Metric } = require('webmetrik')
|
||||||
|
|
||||||
const plog = new LogType("Player")
|
const plog = new LogType("Player")
|
||||||
const clog = new LogType("Signal")
|
const clog = new LogType("Signal")
|
||||||
@@ -21,6 +22,7 @@ class Player {
|
|||||||
player;
|
player;
|
||||||
guildId;
|
guildId;
|
||||||
channelId;
|
channelId;
|
||||||
|
channelName;
|
||||||
queue;
|
queue;
|
||||||
currentResource;
|
currentResource;
|
||||||
loop = false;
|
loop = false;
|
||||||
@@ -29,7 +31,9 @@ class Player {
|
|||||||
clog.error("Impossible de créer un Player, car guildId est null")
|
clog.error("Impossible de créer un Player, car guildId est null")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if(AllPlayers.has(guildId)) {
|
if(AllPlayers.has(guildId)) {
|
||||||
|
|
||||||
return AllPlayers.get(guildId)
|
return AllPlayers.get(guildId)
|
||||||
}
|
}
|
||||||
this.connection = null
|
this.connection = null
|
||||||
@@ -37,6 +41,7 @@ class Player {
|
|||||||
this.guildId = guildId
|
this.guildId = guildId
|
||||||
this.queue = new List(guildId)
|
this.queue = new List(guildId)
|
||||||
AllPlayers.set(guildId, this)
|
AllPlayers.set(guildId, this)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async join(channel) {
|
async join(channel) {
|
||||||
@@ -59,6 +64,7 @@ class Player {
|
|||||||
|
|
||||||
joinChannel(channel) {
|
joinChannel(channel) {
|
||||||
this.channelId = channel.id
|
this.channelId = channel.id
|
||||||
|
this.channelName = channel.name
|
||||||
this.connection = joinVoiceChannel({
|
this.connection = joinVoiceChannel({
|
||||||
channelId: channel.id,
|
channelId: channel.id,
|
||||||
guildId: channel.guild.id,
|
guildId: channel.guild.id,
|
||||||
@@ -77,6 +83,8 @@ class Player {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.connected = true
|
this.connected = true
|
||||||
|
AllPlayers.set(this.guildId, this)
|
||||||
|
|
||||||
process.emit("PLAYERS_UPDATE")
|
process.emit("PLAYERS_UPDATE")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -119,7 +127,7 @@ class Player {
|
|||||||
|
|
||||||
checkConnection() {
|
checkConnection() {
|
||||||
if(this.connection === null) {
|
if(this.connection === null) {
|
||||||
clog.error(`GUILD : ${this.guildId} - La connection n'est pas définie`)
|
// clog.error(`GUILD : ${this.guildId} - La connection n'est pas définie`)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if(this.player === null) {
|
if(this.player === null) {
|
||||||
@@ -134,7 +142,7 @@ class Player {
|
|||||||
const state = {
|
const state = {
|
||||||
current: this.queue.current,
|
current: this.queue.current,
|
||||||
next: this.queue.next,
|
next: this.queue.next,
|
||||||
previous: this.queue.previous,
|
previous: this.queue.getPrevious(),
|
||||||
loop: this.loop,
|
loop: this.loop,
|
||||||
shuffle: this.queue.shuffle,
|
shuffle: this.queue.shuffle,
|
||||||
paused: playerStatus === AudioPlayerStatus.Paused,
|
paused: playerStatus === AudioPlayerStatus.Paused,
|
||||||
@@ -143,6 +151,7 @@ class Player {
|
|||||||
playerState: playerStatus,
|
playerState: playerStatus,
|
||||||
connectionState: connectionStatus,
|
connectionState: connectionStatus,
|
||||||
channelId: this.channelId,
|
channelId: this.channelId,
|
||||||
|
channelName: this.channelName,
|
||||||
guildId: this.guildId,
|
guildId: this.guildId,
|
||||||
}
|
}
|
||||||
return state
|
return state
|
||||||
@@ -171,12 +180,19 @@ class Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async play(song) {
|
async play(song) {
|
||||||
|
|
||||||
if(!songCheck.checkSong(song)) return
|
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()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var numberOfMusicPlayedPerServer = new Metric("numberOfMusicPlayed_" + this.guildId, "Nombre de musiques jouées sur le serveur : " + this.guildId)
|
||||||
|
numberOfMusicPlayedPerServer.setValue(numberOfMusicPlayedPerServer.getValue() + 1)
|
||||||
|
|
||||||
|
var numberOfSecondsPlayedPerServer = new Metric("numberOfSecondsPlayed_" + this.guildId, "Temps jouée sur le serveur : " + this.guildId)
|
||||||
|
numberOfSecondsPlayedPerServer.setValue(numberOfSecondsPlayedPerServer.getValue() + song.duration)
|
||||||
|
|
||||||
this.queue.setCurrent(song)
|
this.queue.setCurrent(song)
|
||||||
this.stream = await this.getStream(song)
|
this.stream = await this.getStream(song)
|
||||||
|
|
||||||
@@ -240,7 +256,6 @@ class Player {
|
|||||||
process.emit("PLAYERS_UPDATE")
|
process.emit("PLAYERS_UPDATE")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
const { LogType } = require('loguix')
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -257,6 +272,7 @@ class Player {
|
|||||||
this.player = null
|
this.player = null
|
||||||
this.connection = null
|
this.connection = null
|
||||||
this.channelId = null
|
this.channelId = null
|
||||||
|
this.channelName = null
|
||||||
this.connected = false
|
this.connected = false
|
||||||
Activity.idleActivity()
|
Activity.idleActivity()
|
||||||
this.queue.destroy()
|
this.queue.destroy()
|
||||||
@@ -291,6 +307,7 @@ class Player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const passThroughStream = new PassThrough();
|
const passThroughStream = new PassThrough();
|
||||||
|
duration = Math.floor(duration.time);
|
||||||
ffmpeg(this.stream)
|
ffmpeg(this.stream)
|
||||||
.setStartTime(duration) // Démarrer à la position demandée (en secondes)
|
.setStartTime(duration) // Démarrer à la position demandée (en secondes)
|
||||||
.outputOptions('-f', 'mp3') // Specify output format if needed
|
.outputOptions('-f', 'mp3') // Specify output format if needed
|
||||||
@@ -398,6 +415,7 @@ function getAllPlayers() {
|
|||||||
AllPlayers.forEach((player) => {
|
AllPlayers.forEach((player) => {
|
||||||
players.push(player)
|
players.push(player)
|
||||||
})
|
})
|
||||||
|
return players
|
||||||
}
|
}
|
||||||
|
|
||||||
function isPlayer(guildId) {
|
function isPlayer(guildId) {
|
||||||
|
@@ -51,31 +51,17 @@ class Song {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async processYoutubeVideo(video, playlist) {
|
async processYoutubeVideo(video) {
|
||||||
if(playlist) {
|
|
||||||
this.title = video.title
|
this.title = video.title
|
||||||
this.author = video.author.name
|
this.author = video.author.name
|
||||||
this.authorId = video.author.channel_url
|
this.authorId = video.author.url
|
||||||
this.thumbnail = video.thumbnail_url
|
this.thumbnail = video.thumbnail
|
||||||
this.url = video.url
|
this.url = "https://www.youtube.com/watch?v=" + video.videoId
|
||||||
this.type = "youtube"
|
this.type = "youtube"
|
||||||
this.id = video.id
|
this.id = video.videoId
|
||||||
|
|
||||||
this.duration = video.milis_length / 1000
|
this.duration = video.duration.seconds
|
||||||
this.readduration = getReadableDuration(this.duration)
|
this.readduration = getReadableDuration(this.duration)
|
||||||
} else {
|
|
||||||
this.title = video.name
|
|
||||||
this.author = video.author.name
|
|
||||||
this.authorId = video.author.url
|
|
||||||
this.thumbnail = video.thumbnail
|
|
||||||
this.url = video.url
|
|
||||||
this.type = "youtube"
|
|
||||||
this.id = video.id
|
|
||||||
|
|
||||||
this.duration = getSecondsDuration(video.duration)
|
|
||||||
this.readduration = getReadableDuration(this.duration)
|
|
||||||
}
|
|
||||||
|
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -26,11 +26,11 @@ function checkSong(song) {
|
|||||||
slog.error("La musique n'a pas d'auteur")
|
slog.error("La musique n'a pas d'auteur")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if(!song.duration) {
|
if(song.duration == null) {
|
||||||
slog.error("La musique n'a pas de durée")
|
slog.error("La musique n'a pas de durée")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if(!song.readduration) {
|
if(song.readduration == null) {
|
||||||
slog.error("La musique n'a pas de durée lisible")
|
slog.error("La musique n'a pas de durée lisible")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,7 @@ const { getReadableDuration } = require("../utils/TimeConverter");
|
|||||||
class Playlist {
|
class Playlist {
|
||||||
title = "Aucun titre";
|
title = "Aucun titre";
|
||||||
id;
|
id;
|
||||||
|
playlistId;
|
||||||
url;
|
url;
|
||||||
author = "Auteur inconnu";
|
author = "Auteur inconnu";
|
||||||
authorId;
|
authorId;
|
||||||
|
@@ -35,27 +35,28 @@ function getPlaylistsOfUser(id) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} id
|
* @param {string} id
|
||||||
* @param {string} name
|
* @param {string} playlistId
|
||||||
* @returns {Playlist}
|
* @returns {Playlist}
|
||||||
*/
|
*/
|
||||||
function getPlaylistOfUser(id, name) {
|
function getPlaylistOfUser(id, playlistId) {
|
||||||
const playlists = getPlaylistsOfUser(id);
|
const playlists = getPlaylistsOfUser(id);
|
||||||
const playlist = playlists.find(p => p.title === name);
|
const playlist = playlists.find(p => p.playlistId === playlistId);
|
||||||
if (!playlist) {
|
if (!playlist) {
|
||||||
clog.warn(`La playlist ${name} n'existe pas pour l'utilisateur ${id}`);
|
clog.warn(`La playlist ${playlistId} n'existe pas pour l'utilisateur ${id}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function addPlaylist(id, name, url) {
|
async function addPlaylist(id, name, url, authorName, authorId, authorAvatar) {
|
||||||
const playlists = getPlaylistsOfUser(id);
|
const playlists = getPlaylistsOfUser(id);
|
||||||
var playlist = new Playlist(name, url);
|
var playlist = new Playlist(name, url);
|
||||||
if (playlists.find(p => p.title === name)) {
|
let failed = false;
|
||||||
clog.warn(`La playlist ${name} existe déjà pour l'utilisateur ${id}`);
|
playlist.thumbnail = null
|
||||||
return;
|
playlist.author = authorName;
|
||||||
}
|
playlist.authorAvatar = `https://cdn.discordapp.com/avatars/${authorId}/${authorAvatar}`;
|
||||||
var failed;
|
playlist.views = null;
|
||||||
|
|
||||||
if(url) {
|
if(url) {
|
||||||
await Finder.search(url, false, "PLAYLIST").then(async (playlistFounded) => {
|
await Finder.search(url, false, "PLAYLIST").then(async (playlistFounded) => {
|
||||||
if(!playlistFounded) {
|
if(!playlistFounded) {
|
||||||
@@ -69,7 +70,7 @@ async function addPlaylist(id, name, url) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
playlist.playlistId = new String(Date.now());
|
||||||
if(failed) {
|
if(failed) {
|
||||||
clog.error(`Impossible de trouver la playlist ${name} pour l'utilisateur ${id}`);
|
clog.error(`Impossible de trouver la playlist ${name} pour l'utilisateur ${id}`);
|
||||||
return null;
|
return null;
|
||||||
@@ -81,65 +82,60 @@ async function addPlaylist(id, name, url) {
|
|||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
function removePlaylist(id, name) {
|
function removePlaylist(id, playlistId) {
|
||||||
const playlists = getPlaylistsOfUser(id);
|
const playlists = getPlaylistsOfUser(id);
|
||||||
const index = playlists.findIndex(p => p.title === name);
|
const index = playlists.findIndex(p => p.playlistId === playlistId);
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
clog.warn(`La playlist ${name} n'existe pas pour l'utilisateur ${id}`);
|
clog.warn(`La playlist ${playlistId} n'existe pas pour l'utilisateur ${id}`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
playlists.splice(index, 1);
|
playlists.splice(index, 1);
|
||||||
playlistDB.save();
|
playlistDB.save();
|
||||||
clog.log(`Suppression de la playlist ${name} pour l'utilisateur ${id}`);
|
clog.log(`Suppression de la playlist ${playlistId} pour l'utilisateur ${id}`);
|
||||||
}
|
}
|
||||||
function getPlaylist(id, name) {
|
function getPlaylist(id, playlistId) {
|
||||||
const playlists = getPlaylistsOfUser(id);
|
const playlists = getPlaylistsOfUser(id);
|
||||||
const playlist = playlists.find(p => p.title === name);
|
const playlist = playlists.find(p => p.playlistId === playlistId);
|
||||||
if (!playlist) {
|
if (!playlist) {
|
||||||
clog.warn(`La playlist ${name} n'existe pas pour l'utilisateur ${id}`);
|
clog.warn(`La playlist ${playlistId} n'existe pas pour l'utilisateur ${id}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return playlist;
|
return playlist;
|
||||||
}
|
}
|
||||||
|
|
||||||
function copyPlaylist(fromId, toId, name) {
|
function copyPlaylist(fromId, toId, playlistId) {
|
||||||
const playlists = getPlaylistsOfUser(fromId);
|
const playlists = getPlaylistsOfUser(fromId);
|
||||||
const playlist = playlists.find(p => p.title === name);
|
const playlist = playlists.find(p => p.playlistId === playlistId);
|
||||||
if (!playlist) {
|
if (!playlist) {
|
||||||
clog.warn(`La playlist ${name} n'existe pas pour l'utilisateur ${fromId}`);
|
clog.warn(`La playlist ${playlistId} n'existe pas pour l'utilisateur ${fromId}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const toPlaylists = getPlaylistsOfUser(toId);
|
const toPlaylists = getPlaylistsOfUser(toId);
|
||||||
// Check if the playlist already exists in the target user
|
// Check if the playlist already exists in the target user
|
||||||
if (toPlaylists.find(p => p.title === name)) {
|
if (toPlaylists.find(p => p.title === playlist.title)) {
|
||||||
clog.warn(`La playlist ${name} existe déjà pour l'utilisateur ${toId}`);
|
clog.warn(`La playlist ${playlist.title} existe déjà pour l'utilisateur ${toId}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
toPlaylists.push(playlist);
|
toPlaylists.push(playlist);
|
||||||
playlistDB.save();
|
playlistDB.save();
|
||||||
clog.log(`Copie de la playlist ${name} de l'utilisateur ${fromId} vers l'utilisateur ${toId}`);
|
clog.log(`Copie de la playlist ${playlist.title} de l'utilisateur ${fromId} vers l'utilisateur ${toId}`);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function renamePlaylist(id, oldName, newName) {
|
function renamePlaylist(id, playlistId, newName) {
|
||||||
const playlists = getPlaylistsOfUser(id);
|
const playlists = getPlaylistsOfUser(id);
|
||||||
const playlist = playlists.find(p => p.title === oldName);
|
const playlist = playlists.find(p => p.playlistId === playlistId);
|
||||||
if (!playlist) {
|
if (!playlist) {
|
||||||
clog.warn(`La playlist ${oldName} n'existe pas pour l'utilisateur ${id}`);
|
clog.warn(`La playlist ${playlistId} n'existe pas pour l'utilisateur ${id}`);
|
||||||
return null;
|
|
||||||
}
|
|
||||||
// Check if the new name already exists
|
|
||||||
if (playlists.find(p => p.title === newName)) {
|
|
||||||
clog.warn(`La playlist ${newName} existe déjà pour l'utilisateur ${id}`);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
playlist.title = newName;
|
playlist.title = newName;
|
||||||
playlistDB.save();
|
playlistDB.save();
|
||||||
clog.log(`Renommage de la playlist ${oldName} en ${newName} pour l'utilisateur ${id}`);
|
clog.log(`Renommage de la playlist ${playlistId} en ${newName} pour l'utilisateur ${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function addSong(id, playlistName, song) {
|
function addSong(id, playlistId, song) {
|
||||||
if(typeof song === "string") {
|
if(typeof song === "string") {
|
||||||
try {
|
try {
|
||||||
song = JSON.parse(song)
|
song = JSON.parse(song)
|
||||||
@@ -154,9 +150,9 @@ function addSong(id, playlistName, song) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const playlists = getPlaylistsOfUser(id);
|
const playlists = getPlaylistsOfUser(id);
|
||||||
const playlist = playlists.find(p => p.title === playlistName);
|
const playlist = playlists.find(p => p.playlistId === playlistId);
|
||||||
if (!playlist) {
|
if (!playlist) {
|
||||||
clog.warn(`La playlist ${playlistName} n'existe pas pour l'utilisateur ${id}`);
|
clog.warn(`La playlist ${playlistId} n'existe pas pour l'utilisateur ${id}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
// Check the integrity of the song
|
// Check the integrity of the song
|
||||||
@@ -165,25 +161,31 @@ function addSong(id, playlistName, song) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
playlist.songs.push(song);
|
playlist.songs.push(song);
|
||||||
|
// Recalculate the songs duration and readduration
|
||||||
|
playlist.duration += song.duration;
|
||||||
|
playlist.readduration = getReadableDuration(playlist.duration);
|
||||||
playlistDB.save();
|
playlistDB.save();
|
||||||
clog.log(`Ajout de la chanson ${song.title} à la playlist ${playlistName} pour l'utilisateur ${id}`);
|
clog.log(`Ajout de la chanson ${song.title} à la playlist ${playlistId} pour l'utilisateur ${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeSong(id, playlistName, songId) {
|
function removeSong(id, playlistId, songId) {
|
||||||
const playlists = getPlaylistsOfUser(id);
|
const playlists = getPlaylistsOfUser(id);
|
||||||
const playlist = playlists.find(p => p.title === playlistName);
|
const playlist = playlists.find(p => p.playlistId === playlistId);
|
||||||
if (!playlist) {
|
if (!playlist) {
|
||||||
clog.warn(`La playlist ${playlistName} n'existe pas pour l'utilisateur ${id}`);
|
clog.warn(`La playlist ${playlistId} n'existe pas pour l'utilisateur ${id}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const index = playlist.songs.findIndex(s => s.id === songId);
|
const index = playlist.songs.findIndex(s => s.id === songId);
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
clog.warn(`La chanson ${songId} n'existe pas dans la playlist ${playlistName} pour l'utilisateur ${id}`);
|
clog.warn(`La chanson ${songId} n'existe pas dans la playlist ${playlistId} pour l'utilisateur ${id}`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
playlist.duration -= playlist.songs[index].duration;
|
||||||
playlist.songs.splice(index, 1);
|
playlist.songs.splice(index, 1);
|
||||||
|
playlist.readduration = getReadableDuration(playlist.duration);
|
||||||
playlistDB.save();
|
playlistDB.save();
|
||||||
clog.log(`Suppression de la chanson ${songId} de la playlist ${playlistName} pour l'utilisateur ${id}`);
|
clog.log(`Suppression de la chanson ${songId} de la playlist ${playlistId} pour l'utilisateur ${id}`);
|
||||||
}
|
}
|
||||||
|
|
||||||
async function processYoutubeData(userId, data) {
|
async function processYoutubeData(userId, data) {
|
||||||
@@ -264,6 +266,55 @@ async function processYoutubeData(userId, data) {
|
|||||||
return playlists;
|
return playlists;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function deleteUserPlaylists(userId) {
|
||||||
|
// Delete all playlists of the user and the keys
|
||||||
|
if (!playlistDB.data[userId]) {
|
||||||
|
clog.warn(`Aucune playlist trouvée pour l'utilisateur ${userId}`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
delete playlistDB.data[userId];
|
||||||
|
playlistDB.save();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function refreshPlaylist(userId, playlistId) {
|
||||||
|
var playlist = getPlaylistOfUser(userId, playlistId);
|
||||||
|
if (!playlist) {
|
||||||
|
clog.warn(`Aucune playlist trouvée pour l'utilisateur ${userId} avec l'ID ${playlistId}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
let failed = false;
|
||||||
|
// If playlistHasUrl, refresh the playlist
|
||||||
|
if (playlist.url) {
|
||||||
|
await Finder.search(playlist.url, false, "PLAYLIST").then(async (playlistFounded) => {
|
||||||
|
if(!playlistFounded) {
|
||||||
|
failed = true;
|
||||||
|
}
|
||||||
|
if(playlistFounded instanceof Playlist) {
|
||||||
|
playlist = playlistFounded;
|
||||||
|
}
|
||||||
|
if(playlist.type === "spotify") {
|
||||||
|
playlist.songs = await spotify.getTracks(playlist);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
if(failed) {
|
||||||
|
clog.warn(`Échec de la mise à jour de la playlist ${playlistId} pour l'utilisateur ${userId}`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
playlist.playlistId = playlistId;
|
||||||
|
const playlists = getPlaylistsOfUser(userId);
|
||||||
|
// Remove the older one
|
||||||
|
// Push at the same index
|
||||||
|
const existingIndex = playlists.findIndex(p => p.playlistId === playlistId);
|
||||||
|
playlists.splice(existingIndex, 1, playlist);
|
||||||
|
playlistDB.save();
|
||||||
|
return playlist;
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
getPlaylistsOfUser,
|
getPlaylistsOfUser,
|
||||||
getPlaylistOfUser,
|
getPlaylistOfUser,
|
||||||
@@ -274,5 +325,7 @@ module.exports = {
|
|||||||
renamePlaylist,
|
renamePlaylist,
|
||||||
addSong,
|
addSong,
|
||||||
removeSong,
|
removeSong,
|
||||||
processYoutubeData
|
processYoutubeData,
|
||||||
|
deleteUserPlaylists,
|
||||||
|
refreshPlaylist
|
||||||
}
|
}
|
@@ -1,5 +1,6 @@
|
|||||||
const {LogType} = require('loguix')
|
const {LogType} = require('loguix')
|
||||||
const wlog = new LogType("Server")
|
const wlog = new LogType("Server")
|
||||||
|
const metrics = require("webmetrik")
|
||||||
|
|
||||||
const fs = require("fs")
|
const fs = require("fs")
|
||||||
const path = require("path")
|
const path = require("path")
|
||||||
@@ -18,6 +19,7 @@ const {__glob} = require("../utils/GlobalVars")
|
|||||||
const playlists = require("../playlists/PlaylistManager")
|
const playlists = require("../playlists/PlaylistManager")
|
||||||
const history = require("../playlists/History")
|
const history = require("../playlists/History")
|
||||||
const lyrics = require("../lyrics/Lyrics")
|
const lyrics = require("../lyrics/Lyrics")
|
||||||
|
const serverSettings = require("../discord/ServerSettings")
|
||||||
const mediaBase = require("../discord/MediaBase")
|
const mediaBase = require("../discord/MediaBase")
|
||||||
const googleApis = require("../playlists/Google/OAuth2")
|
const googleApis = require("../playlists/Google/OAuth2")
|
||||||
const youtubeApi = require("../playlists/Google/YoutubeList")
|
const youtubeApi = require("../playlists/Google/YoutubeList")
|
||||||
@@ -33,8 +35,6 @@ const allConnectedUsers = new Array()
|
|||||||
const guildConnectedUsers = new Map()
|
const guildConnectedUsers = new Map()
|
||||||
const UsersBySocket = new Map()
|
const UsersBySocket = new Map()
|
||||||
|
|
||||||
//TODO: Refactor this file to implement the fact that server can be joined and leaved and all the events are now handled, so guildId is not required for every event
|
|
||||||
|
|
||||||
function init() {
|
function init() {
|
||||||
|
|
||||||
wlog.step.init("server_init", "Initialisation du serveur Socket.IO")
|
wlog.step.init("server_init", "Initialisation du serveur Socket.IO")
|
||||||
@@ -44,16 +44,17 @@ function init() {
|
|||||||
cors: {
|
cors: {
|
||||||
origin: "*"
|
origin: "*"
|
||||||
},
|
},
|
||||||
|
maxHttpBufferSize: 300 * 1024 * 1024
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
process.on("PLAYERS_UPDATE", () => {
|
process.on("PLAYERS_UPDATE", () => {
|
||||||
if(io) {
|
if(io) {
|
||||||
|
io.sockets.emit("/GUILD/UPDATE")
|
||||||
// Get all players and send them to client subscribed to the guild
|
// Get all players and send them to client subscribed to the guild
|
||||||
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")
|
||||||
}
|
}
|
||||||
@@ -61,7 +62,7 @@ function init() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
process.on("USERS_UPDATE", () => {
|
process.on("USERS_UPDATE", async () => {
|
||||||
if(io) {
|
if(io) {
|
||||||
// Get all players and send them to client subscribed to the guild
|
// Get all players and send them to client subscribed to the guild
|
||||||
for(var guild of discordBot.getGuilds().keys()) {
|
for(var guild of discordBot.getGuilds().keys()) {
|
||||||
@@ -75,6 +76,12 @@ function init() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
process.on("VOCAL_UPDATE", async () => {
|
||||||
|
if(io) {
|
||||||
|
io.sockets.emit("/CHANNEL/UPDATE")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
io.on("connection", async (socket) => {
|
io.on("connection", async (socket) => {
|
||||||
var socketUser;
|
var socketUser;
|
||||||
|
|
||||||
@@ -86,9 +93,9 @@ function init() {
|
|||||||
|
|
||||||
wlog.log(`Connexion d'un client : ${socket.id}`)
|
wlog.log(`Connexion d'un client : ${socket.id}`)
|
||||||
|
|
||||||
socket.on("disconnect", () => {
|
socket.on("disconnect", (info) => {
|
||||||
handleDisconnect()
|
handleDisconnect()
|
||||||
wlog.log("Déconnexion du client : " + socket.id)
|
wlog.log("Déconnexion du client : " + socket.id + " - Raison : " + info)
|
||||||
})
|
})
|
||||||
|
|
||||||
socket.on("error", (error) => {
|
socket.on("error", (error) => {
|
||||||
@@ -123,11 +130,6 @@ function init() {
|
|||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
const loggedUser = await users.addUser(discordUser.auth, discordUser.identity)
|
const loggedUser = await users.addUser(discordUser.auth, discordUser.identity)
|
||||||
for(var guild of discordUser.guilds) {
|
|
||||||
if(guild.owner) {
|
|
||||||
users.setGuildOwner(loggedUser.identity.id, guild.id, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
const newToken = await loggedUser.createToken()
|
const newToken = await loggedUser.createToken()
|
||||||
socket.emit("NEW_TOKEN", newToken)
|
socket.emit("NEW_TOKEN", newToken)
|
||||||
token = newToken
|
token = newToken
|
||||||
@@ -220,56 +222,22 @@ function init() {
|
|||||||
|
|
||||||
// CHECKED : 24/04/2025
|
// CHECKED : 24/04/2025
|
||||||
IORequest("/USER/INFO", () => {
|
IORequest("/USER/INFO", () => {
|
||||||
var guildPresents = new Array();
|
socketUser = users.getUserById(socketUser.identity.id)
|
||||||
var guildsOfBot = discordBot.getGuilds()
|
socketUser.identity['isAdmin'] = socketUser.isAdmin()
|
||||||
for(var guild of guildsOfBot) {
|
var guildPresents = getUserGuilds();
|
||||||
if(guild[1].allMembers.includes(socketUser.identity.id)) {
|
|
||||||
const guildData = guild[1]
|
|
||||||
guildData['members'] = new Array()
|
|
||||||
guildData.serverMember = guild[1].allMembers.length
|
|
||||||
for(var user of guildConnectedUsers.get(guild[0]) || []) {
|
|
||||||
const userData = users.getUserById(user.id)
|
|
||||||
if(userData && userData.identity.id != socketUser.identity.id) {
|
|
||||||
let infos = {
|
|
||||||
id: userData.identity.id,
|
|
||||||
username: userData.identity.username,
|
|
||||||
avatar: userData.identity.avatar,
|
|
||||||
isAdmin: userData.isAdmin(),
|
|
||||||
isOwner: userData.isOwner(guild[0]),
|
|
||||||
isMod: userData.isMod(guild[0]),
|
|
||||||
}
|
|
||||||
guildData.members.push(infos)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Send if the bot is connected to the guild
|
|
||||||
if(players.getPlayer(guild[0]) && players.getPlayer(guild[0]).isConnected()) {
|
|
||||||
guildData.connected = true
|
|
||||||
} else {
|
|
||||||
guildData.connected = false
|
|
||||||
}
|
|
||||||
// Leave the room if the user is not in the guild
|
|
||||||
if(socket.rooms.has(guild[0]) && !checkUserGuild(socketUser, guild[0])) {
|
|
||||||
socket.leave(guild[0])
|
|
||||||
removeGuildConnectedUser(socketUser.identity)
|
|
||||||
wlog.warn("L'utilisateur '" + socketUser.identity.username + "' quitte la room de la guilde : " + guild[0] + " car il n'est pas dans la guilde) /!\\")
|
|
||||||
}
|
|
||||||
guildPresents.push(guildData)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IOAnswer("/USER/INFO", {
|
IOAnswer("/USER/INFO", {
|
||||||
identity: socketUser.identity,
|
identity: socketUser.identity,
|
||||||
guilds: guildPresents,
|
guilds: guildPresents,
|
||||||
labels: socketUser.labels,
|
labels: socketUser.labels,
|
||||||
history: history.getPersonalHistory(socketUser.identity.id),
|
history: history.getPersonalHistory(socketUser.identity.id),
|
||||||
})
|
}, true)
|
||||||
wlog.log("Envoi des informations Discord de '" + socketUser.identity.id + "' à '" + socket.id + "'" )
|
wlog.log("[USUAL] - Envoi des informations Discord de '" + socketUser.identity.id + "' à '" + socket.id + "'" )
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
IORequest("/USER/HISTORY", () => {
|
IORequest("/USER/HISTORY", () => {
|
||||||
IOAnswer("/USER/HISTORY", history.getPersonalHistory(socketUser.identity.id))
|
IOAnswer("/USER/HISTORY", history.getPersonalHistory(socketUser.identity.id), true)
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
//CHECKED : 24/04/2025
|
//CHECKED : 24/04/2025
|
||||||
IORequest("/USER/SIGNOUT", () => {
|
IORequest("/USER/SIGNOUT", () => {
|
||||||
@@ -278,6 +246,15 @@ function init() {
|
|||||||
socket.disconnect()
|
socket.disconnect()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
IORequest("/USER/DELETE", async () => {
|
||||||
|
socketUser.removeToken(token)
|
||||||
|
await users.deleteAccount(socketUser.identity.id)
|
||||||
|
await playlists.deleteUserPlaylists(socketUser.identity.id)
|
||||||
|
await history.clearPersonalHistory(socketUser.identity.id)
|
||||||
|
await IOAnswer("/USER/DELETE", true)
|
||||||
|
socket.disconnect()
|
||||||
|
})
|
||||||
|
|
||||||
// CHECKED : 24/04/2025
|
// CHECKED : 24/04/2025
|
||||||
IORequest("/USERS/LIST", () => {
|
IORequest("/USERS/LIST", () => {
|
||||||
if(!checkUserGuild(socketUser, actualGuildId)) return
|
if(!checkUserGuild(socketUser, actualGuildId)) return
|
||||||
@@ -285,6 +262,20 @@ function init() {
|
|||||||
IOAnswer("/USERS/LIST", guildConnectedUsers.get(actualGuildId))
|
IOAnswer("/USERS/LIST", guildConnectedUsers.get(actualGuildId))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
IORequest("/VERSION", () => {
|
||||||
|
IOAnswer("/VERSION", __glob.VERSION)
|
||||||
|
})
|
||||||
|
|
||||||
|
IORequest("/CHANGELOG", () => {
|
||||||
|
const changelogPath = __glob.CHANGELOG_PATH
|
||||||
|
if(!fs.existsSync(changelogPath)) {
|
||||||
|
wlog.warn("Aucun changelog trouvé à l'emplacement : " + changelogPath)
|
||||||
|
return IOAnswer("/CHANGELOG", false)
|
||||||
|
}
|
||||||
|
const changelogContent = fs.readFileSync(changelogPath, "utf-8")
|
||||||
|
IOAnswer("/CHANGELOG", changelogContent, true)
|
||||||
|
}, true)
|
||||||
|
|
||||||
// PLAYERS
|
// PLAYERS
|
||||||
|
|
||||||
IORequest("/PLAYER/LYRICS", async () => {
|
IORequest("/PLAYER/LYRICS", async () => {
|
||||||
@@ -317,38 +308,81 @@ function init() {
|
|||||||
|
|
||||||
// ChECKED : 03/05/2025
|
// ChECKED : 03/05/2025
|
||||||
IORequest("/GUILD/JOIN", async (guildId) => {
|
IORequest("/GUILD/JOIN", async (guildId) => {
|
||||||
if(!checkUserGuild(socketUser, guildId)) return IOAnswer("/GUILD/JOIN", "No guild found or not in the guild")
|
if(!checkUserGuild(socketUser, guildId)) return IOAnswer("/GUILD/JOIN", false)
|
||||||
if(socket.rooms.has(guildId)) {
|
if(socket.rooms.has(guildId)) {
|
||||||
wlog.warn("L'utilisateur '" + socketUser.identity.username + "' est déjà dans la room de la guilde : " + guildId)
|
wlog.warn("[USUAL] - L'utilisateur '" + socketUser.identity.username + "' est déjà dans la room de la guilde : " + guildId)
|
||||||
|
IOAnswer("/GUILD/JOIN", true, true)
|
||||||
} else {
|
} else {
|
||||||
// Make him to leave all the other rooms except the ADMIN room if he is admin
|
// Make him to leave all the other rooms except the ADMIN room if he is admin
|
||||||
await socket.rooms.forEach((room) => {
|
await socket.rooms.forEach((room) => {
|
||||||
if(room != "ADMIN" && room != guildId && room != socket.id) {
|
if(room != "ADMIN" && room != guildId && room != socket.id) {
|
||||||
socket.leave(room)
|
socket.leave(room)
|
||||||
wlog.log("L'utilisateur '" + socketUser.identity.username + "' quitte la room de la guilde: " + room)
|
wlog.log("L'utilisateur '" + socketUser.identity.username + "' quitte la room de la guilde: " + room)
|
||||||
removeGuildConnectedUser(socketUser.identity)
|
removeGuildConnectedUser(socketUser.identity.id)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
socket.join(guildId)
|
socket.join(guildId)
|
||||||
wlog.log("L'utilisateur '" + socketUser.identity.username + "' rejoint la room de la guilde : " + guildId)
|
wlog.log("L'utilisateur '" + socketUser.identity.username + "' rejoint la room de la guilde : " + guildId)
|
||||||
addGuildConnectedUser(socketUser.identity, guildId)
|
addGuildConnectedUser(socketUser.identity, guildId)
|
||||||
actualGuildId = guildId
|
actualGuildId = guildId
|
||||||
IOAnswer("/GUILD/JOIN", true)
|
IOAnswer("/GUILD/JOIN", true, true)
|
||||||
process.emit("PLAYERS_UPDATE")
|
process.emit("PLAYERS_UPDATE")
|
||||||
process.emit("USERS_UPDATE")
|
process.emit("USERS_UPDATE")
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
|
IORequest("/GUILD/INFO", () => {
|
||||||
|
if(!checkUserGuild(socketUser, actualGuildId)) return IOAnswer("/GUILD/INFO", false)
|
||||||
|
const guild = discordBot.getGuilds().get(actualGuildId)
|
||||||
|
if(!guild) {
|
||||||
|
wlog.warn("Aucune guilde trouvée pour l'id : " + actualGuildId)
|
||||||
|
return IOAnswer("/GUILD/INFO", false)
|
||||||
|
}
|
||||||
|
const guildData = {
|
||||||
|
id: guild.id,
|
||||||
|
name: guild.name,
|
||||||
|
icon: guild.icon,
|
||||||
|
owner: guild.owner,
|
||||||
|
members: new Array(),
|
||||||
|
serverMember: guild.allMembers.length,
|
||||||
|
connected: players.getPlayer(actualGuildId) && players.getPlayer(actualGuildId).isConnected(),
|
||||||
|
labels: socketUser.labels,
|
||||||
|
isOwner: socketUser.identity.id === guild.owner,
|
||||||
|
isMod: socketUser.isMod(actualGuildId),
|
||||||
|
isAdmin: socketUser.isAdmin(),
|
||||||
|
}
|
||||||
|
for(var user of guildConnectedUsers.get(actualGuildId) || []) {
|
||||||
|
const userData = users.getUserById(user.id)
|
||||||
|
if(userData && userData.identity.id != socketUser.identity.id) {
|
||||||
|
let infos = {
|
||||||
|
id: userData.identity.id,
|
||||||
|
username: userData.identity.username,
|
||||||
|
global_name: userData.identity.global_name,
|
||||||
|
avatar: userData.identity.avatar,
|
||||||
|
isAdmin: userData.isAdmin(),
|
||||||
|
isOwner: userData.identity.id == guild.owner,
|
||||||
|
isMod: userData.isMod(actualGuildId),
|
||||||
|
}
|
||||||
|
if(guildData.members.find(m => m.id == infos.id)) continue
|
||||||
|
guildData.members.push(infos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IOAnswer("/GUILD/INFO", guildData, true)
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
|
||||||
|
IORequest("/GUILD/LIST", () => {
|
||||||
|
const guildData = getUserGuilds()
|
||||||
|
IOAnswer("/GUILD/LIST", guildData, true)
|
||||||
|
}, true)
|
||||||
|
|
||||||
// CHECKED : 03/05/2025
|
// CHECKED : 03/05/2025
|
||||||
IORequest("/PLAYER/STATE", async () => {
|
IORequest("/PLAYER/STATE", async () => {
|
||||||
const plaryer = await verifyPlayerAction(actualGuildId)
|
const player = await verifyPlayerAction(actualGuildId)
|
||||||
if(!player) return IOAnswer("/PLAYER/STATE", false)
|
if(!player) return IOAnswer("/PLAYER/STATE", false)
|
||||||
IOAnswer("/PLAYER/STATE", await player.getState())
|
IOAnswer("/PLAYER/STATE", await player.getState(), true)
|
||||||
})
|
}, true)
|
||||||
|
|
||||||
|
|
||||||
// CHECKED : 03/05/2025
|
// CHECKED : 03/05/2025
|
||||||
@@ -384,7 +418,7 @@ function init() {
|
|||||||
// CHECKED : 03/05/2025
|
// CHECKED : 03/05/2025
|
||||||
IORequest("/PLAYER/CHANNEL/CHANGE", () => {
|
IORequest("/PLAYER/CHANNEL/CHANGE", () => {
|
||||||
handlePlayerAction(actualGuildId, (player) => {
|
handlePlayerAction(actualGuildId, (player) => {
|
||||||
const channel = getUserChannel()
|
const channel = getUserChannel(false, true)
|
||||||
if(!channel) {
|
if(!channel) {
|
||||||
IOAnswer("/PLAYER/CHANNEL/CHANGE", false)
|
IOAnswer("/PLAYER/CHANNEL/CHANGE", false)
|
||||||
return
|
return
|
||||||
@@ -409,10 +443,10 @@ function init() {
|
|||||||
|
|
||||||
// CHECKED : 04/05/2025
|
// CHECKED : 04/05/2025
|
||||||
IORequest("/QUEUE/PLAY", (data) => {
|
IORequest("/QUEUE/PLAY", (data) => {
|
||||||
if(!data) return IOAnswer("/QUEUE/PLAY/NOW", false)
|
if(!data) return IOAnswer("/QUEUE/PLAY", false)
|
||||||
const {index, listType, now} = data
|
const {index, listType, now} = data
|
||||||
if(!index) return IOAnswer("/QUEUE/PLAY/NOW", false)
|
if(index == null) return IOAnswer("/QUEUE/PLAY", false)
|
||||||
if(!listType) return IOAnswer("/QUEUE/PLAY/NOW", false)
|
if(listType == null) return IOAnswer("/QUEUE/PLAY", false)
|
||||||
if(!checkUserGuild(socketUser, actualGuildId)) return
|
if(!checkUserGuild(socketUser, actualGuildId)) return
|
||||||
const player = new Player(actualGuildId)
|
const player = new Player(actualGuildId)
|
||||||
if(!connectToPlayer(actualGuildId, player)) return IOAnswer("/QUEUE/PLAY", false)
|
if(!connectToPlayer(actualGuildId, player)) return IOAnswer("/QUEUE/PLAY", false)
|
||||||
@@ -424,7 +458,7 @@ function init() {
|
|||||||
const next = player.queue.getNext()
|
const next = player.queue.getNext()
|
||||||
song = next[index]
|
song = next[index]
|
||||||
}
|
}
|
||||||
if(!song) return IOAnswer("/QUEUE/PLAY/NOW", false)
|
if(!song) return IOAnswer("/QUEUE/PLAY", false)
|
||||||
if(listType == "next") player.queue.removeNextByIndex(index)
|
if(listType == "next") player.queue.removeNextByIndex(index)
|
||||||
if(now) {
|
if(now) {
|
||||||
player.play(song)
|
player.play(song)
|
||||||
@@ -432,12 +466,12 @@ function init() {
|
|||||||
player.add(song)
|
player.add(song)
|
||||||
}
|
}
|
||||||
history.addToPersonalHistory(socketUser.identity.id, song)
|
history.addToPersonalHistory(socketUser.identity.id, song)
|
||||||
IOAnswer("/QUEUE/PLAY/NOW", true)
|
IOAnswer("/QUEUE/PLAY", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
// CHECKED : 04/05/2025
|
// CHECKED : 04/05/2025
|
||||||
IORequest("/QUEUE/NEXT/DELETE", (index) => {
|
IORequest("/QUEUE/NEXT/DELETE", (index) => {
|
||||||
if(!index) return IOAnswer("/QUEUE/NEXT/DELETE", false)
|
if(index == null) return IOAnswer("/QUEUE/NEXT/DELETE", false)
|
||||||
handlePlayerAction(actualGuildId, (player) => {
|
handlePlayerAction(actualGuildId, (player) => {
|
||||||
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);
|
||||||
@@ -454,8 +488,8 @@ function init() {
|
|||||||
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 {index, newIndex} = data
|
const {index, newIndex} = data
|
||||||
if(!index) return IOAnswer("/QUEUE/NEXT/MOVE", false)
|
if(index == null) return IOAnswer("/QUEUE/NEXT/MOVE", false)
|
||||||
if(!newIndex) return IOAnswer("/QUEUE/NEXT/MOVE", false)
|
if(newIndex == null) return IOAnswer("/QUEUE/NEXT/MOVE", false)
|
||||||
handlePlayerAction(actualGuildId, (player) => {
|
handlePlayerAction(actualGuildId, (player) => {
|
||||||
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);
|
||||||
@@ -478,6 +512,7 @@ function init() {
|
|||||||
if(typeof song == "string") {
|
if(typeof song == "string") {
|
||||||
song = JSON.parse(song)
|
song = JSON.parse(song)
|
||||||
}
|
}
|
||||||
|
song = new Song(song)
|
||||||
if(!checkUserGuild(socketUser, actualGuildId)) return
|
if(!checkUserGuild(socketUser, actualGuildId)) return
|
||||||
const player = new Player(actualGuildId)
|
const player = new Player(actualGuildId)
|
||||||
if(!connectToPlayer(actualGuildId, player)) return IOAnswer("/SEARCH/PLAY", false)
|
if(!connectToPlayer(actualGuildId, player)) return IOAnswer("/SEARCH/PLAY", false)
|
||||||
@@ -523,26 +558,20 @@ function init() {
|
|||||||
wlog.warn("Le fichier envoyé n'est pas un fichier audio valide (MP3/WAV)")
|
wlog.warn("Le fichier envoyé n'est pas un fichier audio valide (MP3/WAV)")
|
||||||
return IOAnswer("/UPLOAD/FILE", false)
|
return IOAnswer("/UPLOAD/FILE", false)
|
||||||
}
|
}
|
||||||
const url = await mediaBase.postMedia(data)
|
const url = await mediaBase.postMedia(data, socketUser.identity.id)
|
||||||
if(!url) return IOAnswer("/UPLOAD/FILE", false)
|
if(!url) return IOAnswer("/UPLOAD/FILE", "TOOHIGH")
|
||||||
IOAnswer("/UPLOAD/FILE", {"url": url, "name": data.name})
|
IOAnswer("/UPLOAD/FILE", {"url": url, "name": data.name})
|
||||||
})
|
})
|
||||||
|
|
||||||
// CHECKED : 29/05/2025
|
IORequest("/UPLOAD/FILES", async () => {
|
||||||
IORequest("/UPLOAD/FILE/GET_SONG", async (data) => {
|
const files = await mediaBase.getAllMedia(socketUser.identity.id)
|
||||||
if(!data) return IOAnswer("/UPLOAD/FILE/GET_SONG", false)
|
IOAnswer("/UPLOAD/FILES", files)
|
||||||
const {name, url} = data
|
})
|
||||||
if(!url) return IOAnswer("/UPLOAD/FILE/GET_SONG", false)
|
|
||||||
if(!name) return IOAnswer("/UPLOAD/FILE/GET_SONG", false)
|
IORequest("/UPLOAD/FILE/DELETE", (data) => {
|
||||||
const song = new Song()
|
if(!data) return IOAnswer("/UPLOAD/FILE/DELETE", false)
|
||||||
if(!song) return IOAnswer("/UPLOAD/FILE/GET_SONG", false)
|
mediaBase.deleteMedia(data, socketUser.identity.id)
|
||||||
await getMediaInformationFromUrl(song, url)
|
IOAnswer("/UPLOAD/FILE/DELETE", true)
|
||||||
song.type = "attachment"
|
|
||||||
song.author = socketUser.identity.username
|
|
||||||
song.authorId = socketUser.identity.id
|
|
||||||
song.title = name
|
|
||||||
song.url = url
|
|
||||||
IOAnswer("/UPLOAD/FILE/GET_SONG", song)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// GOOGLE API
|
// GOOGLE API
|
||||||
@@ -567,24 +596,27 @@ function init() {
|
|||||||
|
|
||||||
// PLAYLISTS
|
// PLAYLISTS
|
||||||
|
|
||||||
|
IORequest("/CHANNEL", () => {
|
||||||
|
// Get the channel of the bot, in actualGuildId if he is connected
|
||||||
|
const channel = getUserChannel(true)
|
||||||
|
if(!channel) return IOAnswer("/CHANNEL", false, true)
|
||||||
|
IOAnswer("/CHANNEL", channel, true)
|
||||||
|
}, true)
|
||||||
|
|
||||||
// CHECKED : 30/04/2025
|
// CHECKED : 30/04/2025
|
||||||
IORequest("/PLAYLISTS/CREATE", async (data) => {
|
IORequest("/PLAYLISTS/CREATE", async (data) => {
|
||||||
if(!data) return IOAnswer("/PLAYLISTS/CREATE", false)
|
if(!data) return IOAnswer("/PLAYLISTS/CREATE", false)
|
||||||
const {name, url} = data
|
const {name, url} = data
|
||||||
if(!name) return IOAnswer("/PLAYLISTS/CREATE", false)
|
if(!name) return IOAnswer("/PLAYLISTS/CREATE", false)
|
||||||
const playlist = await playlists.addPlaylist(socketUser.identity.id, name, url)
|
const playlist = await playlists.addPlaylist(socketUser.identity.id, name, url, socketUser.identity.username, socketUser.identity.id, socketUser.identity.avatar)
|
||||||
if(!playlist) return IOAnswer("/PLAYLISTS/CREATE", false)
|
if(!playlist) return IOAnswer("/PLAYLISTS/CREATE", false)
|
||||||
IOAnswer("/PLAYLISTS/CREATE", true)
|
IOAnswer("/PLAYLISTS/CREATE", playlist)
|
||||||
})
|
})
|
||||||
|
|
||||||
// CHECKED : 30/04/2025
|
// CHECKED : 30/04/2025
|
||||||
IORequest("/PLAYLISTS/DELETE", (data) => {
|
IORequest("/PLAYLISTS/DELETE", (data) => {
|
||||||
if(!data) return IOAnswer("/PLAYLISTS/DELETE", false)
|
if(!data) return IOAnswer("/PLAYLISTS/DELETE", false)
|
||||||
const {name} = data
|
playlists.removePlaylist(socketUser.identity.id, data)
|
||||||
if(!name) return IOAnswer("/PLAYLISTS/DELETE", false)
|
|
||||||
playlists.removePlaylist(socketUser.identity.id, name)
|
|
||||||
IOAnswer("/PLAYLISTS/DELETE", true)
|
IOAnswer("/PLAYLISTS/DELETE", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -614,34 +646,39 @@ function init() {
|
|||||||
// CHECKED : 30/04/2025
|
// CHECKED : 30/04/2025
|
||||||
IORequest("/PLAYLISTS/RENAME", (data) => {
|
IORequest("/PLAYLISTS/RENAME", (data) => {
|
||||||
if(!data) return IOAnswer("/PLAYLISTS/RENAME", false)
|
if(!data) return IOAnswer("/PLAYLISTS/RENAME", false)
|
||||||
const {name, newName} = data
|
const {id, newName} = data
|
||||||
if(!name || !newName) return IOAnswer("/PLAYLISTS/RENAME", false)
|
if(!id || !newName) return IOAnswer("/PLAYLISTS/RENAME", false)
|
||||||
const playlist = playlists.getPlaylistOfUser(socketUser.identity.id, name)
|
var playlist = playlists.getPlaylist(socketUser.identity.id, id)
|
||||||
if(!playlist) return IOAnswer("/PLAYLISTS/RENAME", false)
|
if(!playlist) return IOAnswer("/PLAYLISTS/RENAME", false)
|
||||||
playlists.renamePlaylist(socketUser.identity.id, name, newName)
|
playlists.renamePlaylist(socketUser.identity.id, id, newName)
|
||||||
IOAnswer("/PLAYLISTS/RENAME", true)
|
playlist = playlists.getPlaylist(socketUser.identity.id, id)
|
||||||
|
IOAnswer("/PLAYLISTS/RENAME", playlist)
|
||||||
})
|
})
|
||||||
|
|
||||||
// CHECKED : 30/04/2025
|
// CHECKED : 30/04/2025
|
||||||
IORequest("/PLAYLISTS/ADD_SONG", (data) => {
|
IORequest("/PLAYLISTS/ADD_SONG", (data) => {
|
||||||
if(!data) return IOAnswer("/PLAYLISTS/ADD_SONG", false)
|
if(!data) return IOAnswer("/PLAYLISTS/ADD_SONG", false)
|
||||||
const {name, song} = data
|
const {id, song} = data
|
||||||
if(!name || !song) return IOAnswer("/PLAYLISTS/ADD_SONG", false)
|
if(!id || !song) return IOAnswer("/PLAYLISTS/ADD_SONG", false)
|
||||||
const playlist = playlists.getPlaylistOfUser(socketUser.identity.id, name)
|
var playlist = playlists.getPlaylistOfUser(socketUser.identity.id, id)
|
||||||
if(!playlist) return IOAnswer("/PLAYLISTS/ADD_SONG", false)
|
if(!playlist) return IOAnswer("/PLAYLISTS/ADD_SONG", false)
|
||||||
playlists.addSong(socketUser.identity.id, name, song)
|
playlists.addSong(socketUser.identity.id, id, song)
|
||||||
IOAnswer("/PLAYLISTS/ADD_SONG", true)
|
playlist = playlists.getPlaylistOfUser(socketUser.identity.id, id)
|
||||||
|
IOAnswer("/PLAYLISTS/ADD_SONG", playlist)
|
||||||
})
|
})
|
||||||
|
|
||||||
// CHECKED : 30/04/2025
|
// CHECKED : 30/04/2025
|
||||||
IORequest("/PLAYLISTS/REMOVE_SONG", (data) => {
|
IORequest("/PLAYLISTS/REMOVE_SONG", (data) => {
|
||||||
if(!data) return IOAnswer("/PLAYLISTS/REMOVE_SONG", false)
|
if(!data) return IOAnswer("/PLAYLISTS/REMOVE_SONG", false)
|
||||||
const {name, songId} = data
|
const {id, songId} = data
|
||||||
if(!name || !songId) return IOAnswer("/PLAYLISTS/REMOVE_SONG", false)
|
if(!id || !songId) return IOAnswer("/PLAYLISTS/REMOVE_SONG", false)
|
||||||
const playlist = playlists.getPlaylistOfUser(socketUser.identity.id, name)
|
var playlist = playlists.getPlaylistOfUser(socketUser.identity.id, id)
|
||||||
if(!playlist) return IOAnswer("/PLAYLISTS/REMOVE_SONG", false)
|
if(!playlist) return IOAnswer("/PLAYLISTS/REMOVE_SONG", false)
|
||||||
playlists.removeSong(socketUser.identity.id, name, songId)
|
|
||||||
IOAnswer("/PLAYLISTS/REMOVE_SONG", true)
|
playlists.removeSong(socketUser.identity.id, id, songId)
|
||||||
|
playlist = playlists.getPlaylistOfUser(socketUser.identity.id, id)
|
||||||
|
|
||||||
|
IOAnswer("/PLAYLISTS/REMOVE_SONG", playlist)
|
||||||
})
|
})
|
||||||
|
|
||||||
// CHECKED : 05/05/2025
|
// CHECKED : 05/05/2025
|
||||||
@@ -658,6 +695,13 @@ function init() {
|
|||||||
IOAnswer("/PLAYLISTS/PLAY", true)
|
IOAnswer("/PLAYLISTS/PLAY", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
IORequest("/PLAYLISTS/REFRESH", async (data) => {
|
||||||
|
if(!data) return IOAnswer("/PLAYLISTS/REFRESH", false)
|
||||||
|
const playlist = await playlists.refreshPlaylist(socketUser.identity.id, data)
|
||||||
|
if(!playlist) return IOAnswer("/PLAYLISTS/REFRESH", false)
|
||||||
|
IOAnswer("/PLAYLISTS/REFRESH", playlist)
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// ADMIN
|
// ADMIN
|
||||||
|
|
||||||
@@ -686,6 +730,7 @@ function init() {
|
|||||||
if(socketUser.identity.id == userId) return IOAnswer("/ADMIN/USERS/SWITCH_ADMIN", false)
|
if(socketUser.identity.id == userId) return IOAnswer("/ADMIN/USERS/SWITCH_ADMIN", false)
|
||||||
if(!users.getUserById(userId)) return IOAnswer("/ADMIN/USERS/SWITCH_ADMIN", false)
|
if(!users.getUserById(userId)) return IOAnswer("/ADMIN/USERS/SWITCH_ADMIN", false)
|
||||||
users.setAdmin(userId)
|
users.setAdmin(userId)
|
||||||
|
process.emit("USERS_UPDATE")
|
||||||
IOAnswer("/ADMIN/USERS/SWITCH_ADMIN", true)
|
IOAnswer("/ADMIN/USERS/SWITCH_ADMIN", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -696,6 +741,7 @@ function init() {
|
|||||||
if(!users.getUserById(userId)) return IOAnswer("/ADMIN/USERS/FULL_BAN", false)
|
if(!users.getUserById(userId)) return IOAnswer("/ADMIN/USERS/FULL_BAN", false)
|
||||||
if(users.getUserById(userId).isAdmin()) return IOAnswer("/ADMIN/USERS/FULL_BAN", false)
|
if(users.getUserById(userId).isAdmin()) return IOAnswer("/ADMIN/USERS/FULL_BAN", false)
|
||||||
users.setFullBan(userId)
|
users.setFullBan(userId)
|
||||||
|
process.emit("USERS_UPDATE")
|
||||||
IOAnswer("/ADMIN/USERS/FULL_BAN", true)
|
IOAnswer("/ADMIN/USERS/FULL_BAN", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -735,45 +781,140 @@ function init() {
|
|||||||
|
|
||||||
|
|
||||||
// CHECKED : 24/04/2025
|
// CHECKED : 24/04/2025
|
||||||
IORequest("/OWNER/USERS/SWITCH_MOD", (userId) => {
|
IORequest("/OWNER/USERS/SWITCH_MOD", async (userId) => {
|
||||||
if(userId || actualGuildId) return IOAnswer("/OWNER/USERS/SWITCH_MOD", false)
|
if(!userId || !actualGuildId) return IOAnswer("/OWNER/USERS/SWITCH_MOD", false)
|
||||||
if(socketUser.identity.id == userId) return IOAnswer("/OWNER/USERS/SWITCH_MOD", false)
|
if(socketUser.identity.id == userId) return IOAnswer("/OWNER/USERS/SWITCH_MOD", false)
|
||||||
if(!socketUser.isOwner(actualGuildId)) return IOAnswer("/OWNER/USERS/SWITCH_MOD", false)
|
const guild = discordBot.getGuilds().get(actualGuildId)
|
||||||
users.setGuildMod(userId, actualGuildId)
|
if(!socketUser.identity.id === guild.owner) return IOAnswer("/OWNER/USERS/SWITCH_MOD", false)
|
||||||
|
if(userId == guild.owner) return IOAnswer("/OWNER/USERS/SWITCH_MOD", false)
|
||||||
|
await users.setGuildMod(userId, actualGuildId)
|
||||||
|
await process.emit("USERS_UPDATE")
|
||||||
IOAnswer("/OWNER/USERS/SWITCH_MOD", true)
|
IOAnswer("/OWNER/USERS/SWITCH_MOD", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
IORequest("/OWNER/ROLES/GET", async () => {
|
||||||
|
if(!actualGuildId) return IOAnswer("/OWNER/ROLES/GET", false)
|
||||||
|
const guild = discordBot.getGuilds().get(actualGuildId)
|
||||||
|
if(!socketUser.identity.id === guild.owner) return IOAnswer("/OWNER/ROLES/GET", false)
|
||||||
|
const rolesSecure = discordBot.getGuildRoles(actualGuildId)
|
||||||
|
const actualRole = await serverSettings.getSecureRole(actualGuildId)
|
||||||
|
// Move the actual role at the start of the array
|
||||||
|
if(actualRole) {
|
||||||
|
const index = rolesSecure.findIndex(r => r.id === actualRole.id)
|
||||||
|
if(index > -1) {
|
||||||
|
rolesSecure.unshift(rolesSecure.splice(index, 1)[0])
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Find the @everyone role and put it at the start of the array
|
||||||
|
const index = rolesSecure.findIndex(r => r.name === "@everyone")
|
||||||
|
if(index > -1) {
|
||||||
|
rolesSecure.unshift(rolesSecure.splice(index, 1)[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IOAnswer("/OWNER/ROLES/GET", await rolesSecure)
|
||||||
|
})
|
||||||
|
|
||||||
|
IORequest("/OWNER/ROLES/SET", async (data) => {
|
||||||
|
if(!actualGuildId) return IOAnswer("/OWNER/ROLES/SET", false)
|
||||||
|
const guild = discordBot.getGuilds().get(actualGuildId)
|
||||||
|
if(!socketUser.identity.id === guild.owner) return IOAnswer("/OWNER/ROLES/SET", false)
|
||||||
|
await serverSettings.setSecureRole(actualGuildId, data)
|
||||||
|
IOAnswer("/OWNER/ROLES/SET", true)
|
||||||
|
})
|
||||||
|
|
||||||
// CHECKED : 24/04/2025
|
// CHECKED : 24/04/2025
|
||||||
IORequest("/MOD/USERS/BAN", (userId) => {
|
IORequest("/MOD/USERS/BAN", async (userId) => {
|
||||||
if(userId || actualGuildId) return IOAnswer("/MOD/USERS/BAN", false)
|
if(!userId || !actualGuildId) return IOAnswer("/MOD/USERS/BAN", false)
|
||||||
|
const guild = discordBot.getGuilds().get(actualGuildId)
|
||||||
|
if(!guild) return IOAnswer("/MOD/USERS/BAN", false)
|
||||||
|
if(!socketUser.isMod(actualGuildId) && socketUser.identity.id !== guild.owner) return IOAnswer("/MOD/USERS/BAN", false)
|
||||||
if(socketUser.identity.id == userId) return IOAnswer("/MOD/USERS/BAN", false)
|
if(socketUser.identity.id == userId) return IOAnswer("/MOD/USERS/BAN", false)
|
||||||
if(!socketUser.isMod(actualGuildId)) return IOAnswer("/MOD/USERS/BAN", false)
|
const user = users.getUserById(userId)
|
||||||
users.setGuildBan(userId, actualGuildId)
|
if(user.isMod(actualGuildId) || user.identity.id == guild.owner) return IOAnswer("/MOD/USERS/BAN", false)
|
||||||
|
await users.setGuildBan(userId, actualGuildId)
|
||||||
|
// If user is connected, disconnect him
|
||||||
|
const userSocket = UsersBySocket.get(userId)
|
||||||
|
if(userSocket) {
|
||||||
|
const socket = io.sockets.sockets.get(userSocket)
|
||||||
|
if(socket) {
|
||||||
|
removeGuildConnectedUser(userId)
|
||||||
|
if(socket.rooms.has(actualGuildId)) {
|
||||||
|
socket.leave(actualGuildId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await process.emit("USERS_UPDATE")
|
||||||
IOAnswer("/MOD/USERS/BAN", true)
|
IOAnswer("/MOD/USERS/BAN", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
IORequest("/MOD/USERS/LIST", () => {
|
||||||
|
if(!actualGuildId) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
const guild = discordBot.getGuilds().get(actualGuildId)
|
||||||
|
if(!guild) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
if(!socketUser.isMod(actualGuildId) && socketUser.identity.id !== guild.owner) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
if(!checkUserGuild(socketUser, actualGuildId)) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
const guildUserList = new Array()
|
||||||
|
for(var user of guild.allMembers) {
|
||||||
|
const userData = users.getUserById(user)
|
||||||
|
if(!userData) continue
|
||||||
|
if(userData.labels.includes("DELETED")) continue
|
||||||
|
userData.identity['isAdmin'] = userData.isAdmin()
|
||||||
|
userData.identity['isMod'] = userData.isMod(actualGuildId)
|
||||||
|
userData.identity['isOwner'] = userData.identity.id == guild.owner
|
||||||
|
guildUserList.push({
|
||||||
|
identity: userData.identity,
|
||||||
|
isBanned: userData.isBanned(actualGuildId),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
IOAnswer("/MOD/USERS/LIST", guildUserList, true)
|
||||||
|
}, true)
|
||||||
|
|
||||||
// UTILS
|
// UTILS
|
||||||
|
|
||||||
// CHECKED : 24/04/2025
|
// CHECKED : 24/04/2025
|
||||||
IORequest("/REPORT", (data) => {
|
IORequest("/REPORT", (data) => {
|
||||||
if(data.length < 2) return IOAnswer("/REPORT", false)
|
if(!data) return IOAnswer("/REPORT", false)
|
||||||
if(!data["level"] || !data["desc"]) return IOAnswer("/REPORT", false)
|
if(!data["level"] || !data["desc"]) return IOAnswer("/REPORT", false)
|
||||||
const report = new Report(socketUser.identity.username, data["level"], data["desc"]).send()
|
const report = new Report(socketUser.identity.username, data["level"], data["desc"]).send()
|
||||||
IOAnswer("/REPORT", true)
|
IOAnswer("/REPORT", true)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
IORequest("/MOD/STATS", () => {
|
||||||
|
if(!actualGuildId) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
const guild = discordBot.getGuilds().get(actualGuildId)
|
||||||
|
if(!guild) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
if(!socketUser.isMod(actualGuildId) && socketUser.identity.id !== guild.owner) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
if(!checkUserGuild(socketUser, actualGuildId)) return IOAnswer("/MOD/USERS/LIST", false)
|
||||||
|
const metrics = JSON.parse(fs.readFileSync(__glob.METRIC_FILE))
|
||||||
|
const metricsToSend = new Array()
|
||||||
|
for(var metric of metrics) {
|
||||||
|
if(metric.name.includes(actualGuildId)) {
|
||||||
|
metricsToSend.push(metric)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
IOAnswer("/MOD/STATS", metricsToSend, true)
|
||||||
|
}, true)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
|
|
||||||
function getUserChannel() {
|
function getUserChannel(usual, force) {
|
||||||
|
const botChannel = getBotChannel()
|
||||||
|
if(botChannel && !force) {
|
||||||
|
return botChannel
|
||||||
|
}
|
||||||
const membersVoices = discordBot.getMembersVoices()
|
const membersVoices = discordBot.getMembersVoices()
|
||||||
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 guildId = member.guildId
|
||||||
|
if(guildId != actualGuildId) {
|
||||||
|
if(!usual) wlog.warn("La guilde active : " + actualGuildId + " ne correspond pas à la guilde du channel vocal : " + guildId + " de l'utilisateur '" + socketUser.identity.username + "'")
|
||||||
|
return null
|
||||||
|
}
|
||||||
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)
|
||||||
@@ -781,11 +922,81 @@ function init() {
|
|||||||
}
|
}
|
||||||
return channel
|
return channel
|
||||||
} else {
|
} else {
|
||||||
wlog.warn("L'utilisateur '" + socketUser.identity.username + "' n'est pas dans un channel vocal")
|
if(!usual) wlog.warn("L'utilisateur '" + socketUser.identity.username + "' n'est pas dans un channel vocal")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getUserGuilds() {
|
||||||
|
var guildPresents = new Array();
|
||||||
|
var guildsOfBot = discordBot.getGuilds()
|
||||||
|
for(var guild of guildsOfBot) {
|
||||||
|
if(guild[1].allMembers.includes(socketUser.identity.id)) {
|
||||||
|
const guildData = guild[1]
|
||||||
|
guildData['members'] = new Array()
|
||||||
|
guildData.serverMember = guild[1].allMembers.length
|
||||||
|
guildData.restricted = false
|
||||||
|
const secureRole = serverSettings.getSecureRole(guild[0])
|
||||||
|
if(secureRole && socketUser.identity.id !== discordBot.getGuilds().get(guild[0]).owner) {
|
||||||
|
const member = discordBot.getGuildMember(guild[0], socketUser.identity.id)
|
||||||
|
if(!member.roles.cache.has(secureRole.id) && socketUser.identity.id !== guild[1].owner && !socketUser.isAdmin()) {
|
||||||
|
guildData.restricted = true
|
||||||
|
} else {
|
||||||
|
guildData.restricted = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
guildData.allowed = true
|
||||||
|
for(var user of guildConnectedUsers.get(guild[0]) || []) {
|
||||||
|
const userData = users.getUserById(user.id)
|
||||||
|
if(userData && userData.identity.id != socketUser.identity.id) {
|
||||||
|
let infos = {
|
||||||
|
id: userData.identity.id,
|
||||||
|
global_name: userData.identity.global_name,
|
||||||
|
username: userData.identity.username,
|
||||||
|
avatar: userData.identity.avatar,
|
||||||
|
isAdmin: userData.isAdmin(),
|
||||||
|
isOwner: userData.identity.id == guild[1].owner,
|
||||||
|
isMod: userData.isMod(guild[0]),
|
||||||
|
}
|
||||||
|
// If it's already in guildData.members, skip
|
||||||
|
if(guildData.members.find(m => m.id == infos.id)) continue
|
||||||
|
guildData.members.push(infos)
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Send if the bot is connected to the guild
|
||||||
|
if(players.getPlayer(guild[0]) && players.getPlayer(guild[0]).isConnected()) {
|
||||||
|
guildData.connected = true
|
||||||
|
} else {
|
||||||
|
guildData.connected = false
|
||||||
|
}
|
||||||
|
// Leave the room if the user is not in the guild
|
||||||
|
if(socket.rooms.has(guild[0]) && !checkUserGuild(socketUser, guild[0])) {
|
||||||
|
socket.leave(guild[0])
|
||||||
|
removeGuildConnectedUser(socketUser.identity.id)
|
||||||
|
wlog.warn("L'utilisateur '" + socketUser.identity.username + "' quitte la room de la guilde : " + guild[0] + " car il n'est pas dans la guilde) /!\\")
|
||||||
|
}
|
||||||
|
guildPresents.push(guildData)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return guildPresents
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBotChannel() {
|
||||||
|
const playersList = players.getAllPlayers()
|
||||||
|
if(!playersList || playersList.length == 0) return null
|
||||||
|
const player = playersList.find(p => p.isConnected() && p.guildId == actualGuildId)
|
||||||
|
if(player) {
|
||||||
|
const channel = discordBot.getChannel(actualGuildId, player.channelId)
|
||||||
|
if(channel) {
|
||||||
|
return channel
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Player} player
|
* @param {Player} player
|
||||||
*/
|
*/
|
||||||
@@ -815,6 +1026,15 @@ function init() {
|
|||||||
wlog.warn("Aucun guildId n'est actif pour l'utilisateur : " + socketUser.identity.username)
|
wlog.warn("Aucun guildId n'est actif pour l'utilisateur : " + socketUser.identity.username)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
// Check role if secure role is set
|
||||||
|
const secureRole = serverSettings.getSecureRole(guildId)
|
||||||
|
if(secureRole && socketUser.identity.id !== discordBot.getGuilds().get(guildId).owner) {
|
||||||
|
const member = discordBot.getGuildMember(guildId, socketUser.identity.id)
|
||||||
|
if(member.roles.cache.has(secureRole.id) == false) {
|
||||||
|
wlog.warn("L'utilisateur '" + socketUser.identity.username + "' n'a pas le rôle requis pour accéder à la guilde : " + guildId)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
// Check if the guildId is referenced in the bot guilds
|
// Check if the guildId is referenced in the bot guilds
|
||||||
if(!discordBot.getGuilds().has(guildId)) {
|
if(!discordBot.getGuilds().has(guildId)) {
|
||||||
wlog.warn("La guilde : " + guildId + " n'est pas référencée dans le bot")
|
wlog.warn("La guilde : " + guildId + " n'est pas référencée dans le bot")
|
||||||
@@ -864,7 +1084,7 @@ function init() {
|
|||||||
if(socketUser) {
|
if(socketUser) {
|
||||||
wlog.log("Déconnexion de l'utilisateur : " + socketUser.identity.username + " (" + socketUser.identity.id + ") - Socket : " + socket.id)
|
wlog.log("Déconnexion de l'utilisateur : " + socketUser.identity.username + " (" + socketUser.identity.id + ") - Socket : " + socket.id)
|
||||||
allConnectedUsers.splice(allConnectedUsers.indexOf(socketUser.identity), 1)
|
allConnectedUsers.splice(allConnectedUsers.indexOf(socketUser.identity), 1)
|
||||||
removeGuildConnectedUser(socketUser.identity)
|
removeGuildConnectedUser(socketUser.identity.id)
|
||||||
process.emit("USERS_UPDATE")
|
process.emit("USERS_UPDATE")
|
||||||
// Remove every rooms include admin
|
// Remove every rooms include admin
|
||||||
socket.rooms.forEach((room) => {
|
socket.rooms.forEach((room) => {
|
||||||
@@ -882,16 +1102,19 @@ function init() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function IORequest(RequestName, RequestCallback) {
|
function IORequest(RequestName, RequestCallback, usual) {
|
||||||
socket.on(RequestName, (value) => {
|
socket.on(RequestName, (value) => {
|
||||||
wlog.log(socketUser.identity.username + " - Socket : " + socket.id + " - " + RequestName + " - [RECIEVED]")
|
if(!usual) {
|
||||||
|
wlog.log(socketUser.identity.username + " - Socket : " + socket.id + " - " + RequestName + " - [RECIEVED]")
|
||||||
|
}
|
||||||
RequestCallback(value)
|
RequestCallback(value)
|
||||||
})
|
})
|
||||||
|
|
||||||
}
|
}
|
||||||
function IOAnswer(AnswerName, AnswerValue) {
|
function IOAnswer(AnswerName, AnswerValue, usual) {
|
||||||
|
if(!usual) {
|
||||||
wlog.log(socketUser.identity.username + " - Socket : " + socket.id + " - " + AnswerName + " - [ANSWERED]")
|
wlog.log(socketUser.identity.username + " - Socket : " + socket.id + " - " + AnswerName + " - [ANSWERED]")
|
||||||
|
}
|
||||||
socket.emit(AnswerName, AnswerValue)
|
socket.emit(AnswerName, AnswerValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -907,27 +1130,29 @@ function init() {
|
|||||||
if(!guildConnectedUsers.has(guildId)) {
|
if(!guildConnectedUsers.has(guildId)) {
|
||||||
guildConnectedUsers.set(guildId, new Array())
|
guildConnectedUsers.set(guildId, new Array())
|
||||||
}
|
}
|
||||||
const users = guildConnectedUsers.get(guildId)
|
|
||||||
if(users.includes(user)) {
|
if(guildConnectedUsers.get(guildId).includes(user)) {
|
||||||
wlog.warn("L'utilisateur '" + user.username + "' est déjà connecté à la guilde : " + guildId)
|
wlog.warn("L'utilisateur '" + user.username + "' est déjà connecté à la guilde : " + guildId)
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
guildConnectedUsers.get(guildId).push(user)
|
||||||
}
|
}
|
||||||
guildConnectedUsers.get(guildId).push(user)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function removeGuildConnectedUser(user) {
|
function removeGuildConnectedUser(userId) {
|
||||||
for(var guild of guildConnectedUsers.keys()) {
|
for(var guild of guildConnectedUsers.keys()) {
|
||||||
const users = guildConnectedUsers.get(guild)
|
const users = guildConnectedUsers.get(guild)
|
||||||
if(users.includes(user)) {
|
const userIndex = users.findIndex(u => u.id == userId)
|
||||||
users.splice(users.indexOf(user), 1)
|
if(userIndex != -1) {
|
||||||
if(users.length == 0) {
|
users.splice(userIndex, 1)
|
||||||
guildConnectedUsers.delete(guild)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -145,15 +145,8 @@ class User {
|
|||||||
return this.labels.includes("ADMIN");
|
return this.labels.includes("ADMIN");
|
||||||
}
|
}
|
||||||
isMod(guildId) {
|
isMod(guildId) {
|
||||||
if(this.isOwner(guildId)) return true;
|
|
||||||
const modLabel = `MOD_${guildId}`;
|
const modLabel = `MOD_${guildId}`;
|
||||||
return this.labels.includes(modLabel);
|
return this.labels.includes(modLabel) || this.isAdmin();
|
||||||
}
|
|
||||||
|
|
||||||
isOwner(guildId) {
|
|
||||||
const ownerLabel = `OWNER_${guildId}`;
|
|
||||||
if(this.isAdmin()) return true;
|
|
||||||
return this.labels.includes(ownerLabel);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
justUpdated() {
|
justUpdated() {
|
||||||
@@ -241,6 +234,10 @@ async function updateIdentity(id) {
|
|||||||
clog.warn(`Utilisateur ${id} non trouvé.`);
|
clog.warn(`Utilisateur ${id} non trouvé.`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if(user.labels.includes("DELETED")) {
|
||||||
|
clog.warn(`L'utilisateur ${user.identity.username} (${user.identity.id}) est marqué comme supprimé, il ne peut pas être mis à jour.`);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
clog.log(`Mise à jour de l'identité de l'utilisateur ${user.identity.username} (${user.identity.id})...`);
|
clog.log(`Mise à jour de l'identité de l'utilisateur ${user.identity.username} (${user.identity.id})...`);
|
||||||
if (user.auth) {
|
if (user.auth) {
|
||||||
const identity = await discordAuth.getUserIdentity(user.auth);
|
const identity = await discordAuth.getUserIdentity(user.auth);
|
||||||
@@ -284,6 +281,10 @@ async function addUser(auth, identity) {
|
|||||||
const existingUser = userList.find(user => user.identity.id === identity.id);
|
const existingUser = userList.find(user => user.identity.id === identity.id);
|
||||||
if (existingUser) {
|
if (existingUser) {
|
||||||
clog.warn(`L'utilisateur ${identity.username} existe déjà.`);
|
clog.warn(`L'utilisateur ${identity.username} existe déjà.`);
|
||||||
|
if(existingUser.labels.includes("DELETED")) {
|
||||||
|
clog.warn(`L'utilisateur ${identity.username} est marqué comme supprimé, il sera réactivé.`);
|
||||||
|
existingUser.labels = existingUser.labels.filter(label => label !== "DELETED");
|
||||||
|
}
|
||||||
// Update the existing user with new information
|
// Update the existing user with new information
|
||||||
existingUser.auth = auth;
|
existingUser.auth = auth;
|
||||||
existingUser.identity = identity;
|
existingUser.identity = identity;
|
||||||
@@ -391,88 +392,88 @@ function getSimpleUser(id) {
|
|||||||
|
|
||||||
// SET LABELS
|
// SET LABELS
|
||||||
|
|
||||||
function setAdmin(id) {
|
async function setAdmin(id) {
|
||||||
const user = getUserById(id);
|
const user = getUserById(id);
|
||||||
if (user) {
|
if (user) {
|
||||||
user.setAdmin();
|
await user.setAdmin();
|
||||||
saveUsers();
|
await saveUsers();
|
||||||
} else {
|
} else {
|
||||||
clog.warn(`Utilisateur ${id} non trouvé.`);
|
clog.warn(`Utilisateur ${id} non trouvé.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGuildMod(id, guildId) {
|
async function setGuildMod(id, guildId) {
|
||||||
const user = getUserById(id);
|
const user = getUserById(id);
|
||||||
if (user) {
|
if (user) {
|
||||||
const modLabel = `MOD_${guildId}`;
|
const modLabel = `MOD_${guildId}`;
|
||||||
if (user.labels.includes(modLabel)) {
|
if (user.labels.includes(modLabel)) {
|
||||||
user.labels.splice(user.labels.indexOf(modLabel), 1);
|
await user.labels.splice(user.labels.indexOf(modLabel), 1);
|
||||||
clog.log(`L'utilisateur ${user.identity.username} n'est plus modérateur du serveur ${guildId}.`);
|
clog.log(`L'utilisateur ${user.identity.username} n'est plus modérateur du serveur ${guildId}.`);
|
||||||
} else {
|
} else {
|
||||||
user.labels.push(modLabel);
|
await user.labels.push(modLabel);
|
||||||
clog.log(`L'utilisateur ${user.identity.username} est maintenant modérateur du serveur ${guildId}.`);
|
clog.log(`L'utilisateur ${user.identity.username} est maintenant modérateur du serveur ${guildId}.`);
|
||||||
}
|
}
|
||||||
saveUsers();
|
await saveUsers();
|
||||||
} else {
|
} else {
|
||||||
clog.warn(`Utilisateur ${id} non trouvé.`);
|
clog.warn(`Utilisateur ${id} non trouvé.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGuildBan(id, guildId) {
|
async function setGuildBan(id, guildId) {
|
||||||
const user = getUserById(id);
|
const user = getUserById(id);
|
||||||
if (user) {
|
if (user) {
|
||||||
if(user.isAdmin()) {
|
if(user.isAdmin()) {
|
||||||
clog.warn(`L'utilisateur ${user.identity.username} est admin, il ne peut pas être banni.`);
|
clog.warn(`L'utilisateur ${user.identity.username} est admin, il ne peut pas être banni.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
user.setBan(guildId);
|
await user.setBan(guildId);
|
||||||
saveUsers();
|
await saveUsers();
|
||||||
} else {
|
} else {
|
||||||
clog.warn(`Utilisateur ${id} non trouvé.`);
|
clog.warn(`Utilisateur ${id} non trouvé.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setFullBan(id) {
|
async function setFullBan(id) {
|
||||||
const user = getUserById(id);
|
const user = getUserById(id);
|
||||||
if (user) {
|
if (user) {
|
||||||
if(user.isAdmin()) {
|
if(user.isAdmin()) {
|
||||||
clog.warn(`L'utilisateur ${user.identity.username} est admin, il ne peut pas être banni.`);
|
clog.warn(`L'utilisateur ${user.identity.username} est admin, il ne peut pas être banni.`);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
user.setFullBan();
|
await user.setFullBan();
|
||||||
saveUsers();
|
await saveUsers();
|
||||||
} else {
|
} else {
|
||||||
clog.warn(`Utilisateur ${id} non trouvé.`);
|
clog.warn(`Utilisateur ${id} non trouvé.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function setGuildOwner(id, guildId, force) {
|
|
||||||
|
function deleteAccount(id) {
|
||||||
const user = getUserById(id);
|
const user = getUserById(id);
|
||||||
if (user) {
|
if (user) {
|
||||||
const ownerLabel = `OWNER_${guildId}`;
|
user.labels = user.labels.filter(label => label.includes('BAN'));
|
||||||
if (user.labels.includes(ownerLabel) && !force) {
|
user.labels.push('DELETED'); // Add a deleted label
|
||||||
user.labels.splice(user.labels.indexOf(ownerLabel), 1);
|
user.tokens = []; // Clear tokens
|
||||||
clog.log(`L'utilisateur ${user.identity.username} n'est plus propriétaire du serveur ${guildId}.`);
|
user.auth = null; // Clear authentication
|
||||||
} else {
|
user.identity = { id: user.identity.id, username: user.identity.username }; // Keep only identity information
|
||||||
if(force && user.labels.includes(ownerLabel)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
user.labels.push(ownerLabel);
|
|
||||||
clog.log(`L'utilisateur ${user.identity.username} est maintenant propriétaire du serveur ${guildId}.`);
|
|
||||||
}
|
|
||||||
saveUsers();
|
saveUsers();
|
||||||
|
clog.log(`Suppression du compte de l'utilisateur ${user.identity.username}.`);
|
||||||
} else {
|
} else {
|
||||||
clog.warn(`Utilisateur ${id} non trouvé.`);
|
clog.warn(`Utilisateur ${id} non trouvé.`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// USERS DB
|
// USERS DB
|
||||||
|
|
||||||
function loadUsers() {
|
function loadUsers() {
|
||||||
UserDB.load()
|
UserDB.load()
|
||||||
userList = new Array();
|
userList = new Array();
|
||||||
for (const user of UserDB.getData()) {
|
for (const user of UserDB.getData()) {
|
||||||
|
if(user?.labels?.includes("DELETED")) {
|
||||||
|
clog.log(`Utilisateur ${user.identity.id} marqué comme supprimé, ignoré.`);
|
||||||
|
userList.push(new User(null, user.identity, [], user.labels));
|
||||||
|
continue; // Skip deleted users
|
||||||
|
}
|
||||||
userList.push(new User(user.auth, user.identity, user.tokens, user.labels));
|
userList.push(new User(user.auth, user.identity, user.tokens, user.labels));
|
||||||
}
|
}
|
||||||
clog.log(`Chargement de ${userList.length} utilisateurs.`);
|
clog.log(`Chargement de ${userList.length} utilisateurs.`);
|
||||||
@@ -506,7 +507,6 @@ function clearNeedUpdateForUsers() {
|
|||||||
module.exports = {User}
|
module.exports = {User}
|
||||||
module.exports = {
|
module.exports = {
|
||||||
addUser,
|
addUser,
|
||||||
setGuildOwner,
|
|
||||||
setFullBan,
|
setFullBan,
|
||||||
removeUser,
|
removeUser,
|
||||||
getUserByToken,
|
getUserByToken,
|
||||||
@@ -522,5 +522,6 @@ module.exports = {
|
|||||||
updateCredientials,
|
updateCredientials,
|
||||||
refreshAllUserInformation,
|
refreshAllUserInformation,
|
||||||
updateIdentity,
|
updateIdentity,
|
||||||
clearNeedUpdateForUsers
|
clearNeedUpdateForUsers,
|
||||||
|
deleteAccount
|
||||||
};
|
};
|
||||||
|
@@ -1,5 +1,6 @@
|
|||||||
const path = require("path")
|
const path = require("path")
|
||||||
const root = path.resolve(__dirname, '../../')
|
const root = path.resolve(__dirname, '../../')
|
||||||
|
const version = JSON.parse(require('fs').readFileSync(root + path.sep + "package.json", "utf-8")).version
|
||||||
|
|
||||||
const __glob = {
|
const __glob = {
|
||||||
PACKAGEINFO: root + path.sep + "package.json",
|
PACKAGEINFO: root + path.sep + "package.json",
|
||||||
@@ -7,13 +8,18 @@ const __glob = {
|
|||||||
SRC: root + path.sep + "src",
|
SRC: root + path.sep + "src",
|
||||||
LOGS: root + path.sep + "logs",
|
LOGS: root + path.sep + "logs",
|
||||||
DATA: root + path.sep + "data",
|
DATA: root + path.sep + "data",
|
||||||
COMMANDS: root + path.sep + "src" + path.sep + "discord" + path.sep + "commands",
|
COMMANDS: root + path.sep + "src" + path.sep + "discord" + path.sep + "Commands",
|
||||||
METRIC_FILE: root + path.sep + "data" + path.sep + "metrics.json",
|
METRIC_FILE: root + path.sep + "data" + path.sep + "metrics.json",
|
||||||
PREVIOUSFILE: root + path.sep + "data" + path.sep + "previous.json",
|
PREVIOUSFILE: root + path.sep + "data" + path.sep + "previous.json",
|
||||||
USERFILE: root + path.sep + "data" + path.sep + "users.json",
|
USERFILE: root + path.sep + "data" + path.sep + "users.json",
|
||||||
PLAYLISTFILE: root + path.sep + "data" + path.sep + "playlists.json",
|
PLAYLISTFILE: root + path.sep + "data" + path.sep + "playlists.json",
|
||||||
HISTORY_DB: root + path.sep + "data" + path.sep + "history.json",
|
HISTORY_DB: root + path.sep + "data" + path.sep + "history.json",
|
||||||
MEDIA_DB: root + path.sep + "data" + path.sep + "media.json",
|
MEDIA_DB: root + path.sep + "data" + path.sep + "media.json",
|
||||||
|
SERVER_DB: root + path.sep + "data" + path.sep + "servers.json",
|
||||||
|
VERSION: version,
|
||||||
|
CHANGELOG_PATH: root + path.sep + "CHANGELOG.html",
|
||||||
|
COOKIES: root + path.sep + "data" + path.sep + "cookies.json",
|
||||||
|
PROXY: root + path.sep + "data" + path.sep + "proxy.json"
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = {__glob}
|
module.exports = {__glob}
|
Reference in New Issue
Block a user