Push structure
This commit is contained in:
parent
da04474185
commit
7d6bc8e12f
14
.env
Normal file
14
.env
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
TOKEN=ODcwNzA3OTcyMjE1NTUwMDE0.GNCXuj.kPaJfU-QHKZk7uBvzblOmJHSv9QllNRIIp5dGg
|
||||||
|
CLIENT_ID=870707972215550014
|
||||||
|
OWNER_ID=574544938440851466
|
||||||
|
|
||||||
|
SUPPORT_SERVER_ID=840770323988873227
|
||||||
|
CHANNEL_REQUEST_ACCESS_ID=1402029493258031114
|
||||||
|
CHANNEL_ACCESS_STAFF_REQUESTS_ID=1429968603905786000
|
||||||
|
|
||||||
|
ROLE_WAITER_ID=1429968069450530987
|
||||||
|
ROLE_VERIFIED_ID=1429968133304615012
|
||||||
|
ROLE_ADMIN_ID=1164572260607205486
|
||||||
|
|
||||||
|
MINECRAFT_SERVER_IP=valloic.dev:25565
|
||||||
|
MINECRAFT_WHITELIST_PATH=/opt/minecraft/server/whitelist.json
|
||||||
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
node_modules
|
||||||
134
README.md
134
README.md
@ -1,3 +1,133 @@
|
|||||||
# mc-acces-bot
|
# Bot Discord - Accès Serveur Minecraft
|
||||||
|
|
||||||
Bot privé pour gérer mon serveur Minecraft.
|
Ce bot Discord permet de gérer automatiquement les demandes d'accès à un serveur Minecraft via un système de whitelist.
|
||||||
|
|
||||||
|
## Fonctionnalités
|
||||||
|
|
||||||
|
### 🎮 Système de demande d'accès
|
||||||
|
- Message automatique avec bouton pour demander l'accès
|
||||||
|
- Modal pour saisir le pseudo Minecraft
|
||||||
|
- Vérification automatique si le joueur est déjà whitelisté
|
||||||
|
- Envoi de la demande au canal staff avec boutons Accept/Refuse
|
||||||
|
|
||||||
|
### ⚙️ Commandes administrateur
|
||||||
|
- `/minecraft list` - Affiche la liste des joueurs whitelistés
|
||||||
|
- `/minecraft add <pseudo>` - Ajoute un joueur à la whitelist
|
||||||
|
- `/minecraft remove <pseudo>` - Retire un joueur de la whitelist
|
||||||
|
- `/minecraft status` - Affiche le statut du serveur Minecraft
|
||||||
|
- `/setup-access` - Envoie le message de demande d'accès
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. **Cloner le projet et installer les dépendances :**
|
||||||
|
```bash
|
||||||
|
npm install
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Configurer le fichier .env :**
|
||||||
|
Assurez-vous que votre fichier `.env` contient toutes les variables nécessaires :
|
||||||
|
```env
|
||||||
|
TOKEN=votre_token_bot_discord
|
||||||
|
CLIENT_ID=id_du_bot
|
||||||
|
OWNER_ID=votre_id_discord
|
||||||
|
|
||||||
|
SUPPORT_SERVER_ID=id_du_serveur_discord
|
||||||
|
CHANNEL_REQUEST_ACCESS_ID=id_canal_demandes_publiques
|
||||||
|
CHANNEL_ACCESS_STAFF_REQUESTS_ID=id_canal_staff_demandes
|
||||||
|
|
||||||
|
ROLE_WAITER_ID=id_role_attente
|
||||||
|
ROLE_VERIFIED_ID=id_role_verifie
|
||||||
|
ROLE_ADMIN_ID=id_role_admin
|
||||||
|
|
||||||
|
MINECRAFT_SERVER_IP=adresse:port
|
||||||
|
MINECRAFT_WHITELIST_PATH=/chemin/vers/whitelist.json
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Lancer le bot :**
|
||||||
|
```bash
|
||||||
|
npm start
|
||||||
|
```
|
||||||
|
|
||||||
|
Pour le développement :
|
||||||
|
```bash
|
||||||
|
npm run dev
|
||||||
|
```
|
||||||
|
|
||||||
|
## Structure du projet
|
||||||
|
|
||||||
|
```
|
||||||
|
├── start.js # Point d'entrée principal
|
||||||
|
├── src/
|
||||||
|
│ ├── commands/
|
||||||
|
│ │ ├── minecraft.js # Commandes /minecraft
|
||||||
|
│ │ └── setup-access.js # Commande /setup-access
|
||||||
|
│ ├── events/
|
||||||
|
│ │ └── ready.js # Événement de démarrage
|
||||||
|
│ ├── handlers/
|
||||||
|
│ │ ├── commandHandler.js # Chargeur de commandes
|
||||||
|
│ │ ├── eventHandler.js # Chargeur d'événements
|
||||||
|
│ │ └── interactionHandler.js # Gestionnaire d'interactions
|
||||||
|
│ └── utils/
|
||||||
|
│ ├── accessRequestManager.js # Gestionnaire de demandes d'accès
|
||||||
|
│ ├── minecraftServer.js # Utilitaires serveur Minecraft
|
||||||
|
│ └── whitelistManager.js # Gestionnaire de whitelist
|
||||||
|
```
|
||||||
|
|
||||||
|
## Utilisation
|
||||||
|
|
||||||
|
### Configuration initiale
|
||||||
|
|
||||||
|
1. **Inviter le bot sur votre serveur** avec les permissions nécessaires
|
||||||
|
2. **Utiliser `/setup-access`** dans le canal où vous voulez le message de demande d'accès
|
||||||
|
3. **Configurer les rôles** dans votre serveur Discord selon les IDs dans le `.env`
|
||||||
|
|
||||||
|
### Workflow des demandes
|
||||||
|
|
||||||
|
1. **Utilisateur :** Clique sur le bouton "Demander l'accès"
|
||||||
|
2. **Utilisateur :** Remplit le modal avec son pseudo Minecraft
|
||||||
|
3. **Système :** Vérifie si le joueur est déjà whitelisté
|
||||||
|
4. **Système :** Envoie la demande au canal staff
|
||||||
|
5. **Staff :** Clique sur "Accepter" ou "Refuser"
|
||||||
|
6. **Système :** Ajoute le joueur à la whitelist (si accepté) et notifie l'utilisateur
|
||||||
|
|
||||||
|
### Commandes administrateur
|
||||||
|
|
||||||
|
Seul l'OWNER_ID peut utiliser les commandes `/minecraft` :
|
||||||
|
|
||||||
|
- **Lister les joueurs :** `/minecraft list`
|
||||||
|
- **Ajouter un joueur :** `/minecraft add pseudo:NomDuJoueur`
|
||||||
|
- **Retirer un joueur :** `/minecraft remove pseudo:NomDuJoueur`
|
||||||
|
- **Status du serveur :** `/minecraft status`
|
||||||
|
|
||||||
|
## Permissions requises
|
||||||
|
|
||||||
|
Le bot a besoin des permissions Discord suivantes :
|
||||||
|
- `Send Messages` - Envoyer des messages
|
||||||
|
- `Use Slash Commands` - Utiliser les commandes slash
|
||||||
|
- `Embed Links` - Incorporer des liens
|
||||||
|
- `Manage Messages` - Gérer les messages
|
||||||
|
- `Read Message History` - Lire l'historique des messages
|
||||||
|
|
||||||
|
## Notes importantes
|
||||||
|
|
||||||
|
- Le fichier `whitelist.json` doit être accessible en lecture/écriture
|
||||||
|
- Le serveur Minecraft doit être accessible pour la vérification du statut
|
||||||
|
- Les IDs Discord dans le `.env` doivent être valides
|
||||||
|
- Le bot vérifie automatiquement les pseudos via l'API Mojang
|
||||||
|
|
||||||
|
## Dépannage
|
||||||
|
|
||||||
|
### Le bot ne répond pas aux commandes
|
||||||
|
- Vérifiez que le TOKEN est correct
|
||||||
|
- Vérifiez que les permissions sont accordées
|
||||||
|
- Consultez les logs dans la console
|
||||||
|
|
||||||
|
### Erreurs de whitelist
|
||||||
|
- Vérifiez le chemin vers `whitelist.json`
|
||||||
|
- Vérifiez les permissions de fichier
|
||||||
|
- Assurez-vous que le format JSON est valide
|
||||||
|
|
||||||
|
### Problèmes de serveur Minecraft
|
||||||
|
- Vérifiez que l'adresse IP et le port sont corrects
|
||||||
|
- Assurez-vous que le serveur est en ligne
|
||||||
|
- Vérifiez les paramètres du pare-feu
|
||||||
9
emojis.json
Normal file
9
emojis.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"added_whitelist_emoji": "<:securityenable:1429980226351534090>",
|
||||||
|
"removed_whitelist_emoji": "<:securitydisable:1429980224984055960>",
|
||||||
|
"refused_whitelist_emoji": "<:securitydisable:1429980224984055960>",
|
||||||
|
"pending_whitelist_emoji": "<:pending:1429980711481245768>",
|
||||||
|
"error_emoji": "<:error:1429980784076521614>",
|
||||||
|
"info_emoji": "<:info:1429981238130774016>",
|
||||||
|
"success_emoji": "<a:success:1429980863663312928>"
|
||||||
|
}
|
||||||
27
package.json
Normal file
27
package.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "mc-access-bot",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "Bot Discord pour gérer l'accès au serveur Minecraft",
|
||||||
|
"main": "start.js",
|
||||||
|
"scripts": {
|
||||||
|
"start": "node start.js",
|
||||||
|
"dev": "nodemon start.js"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"discord",
|
||||||
|
"minecraft",
|
||||||
|
"bot",
|
||||||
|
"whitelist"
|
||||||
|
],
|
||||||
|
"author": "",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"discord.js": "^14.14.1",
|
||||||
|
"dotenv": "^16.3.1",
|
||||||
|
"minecraft-server-util": "^5.4.3",
|
||||||
|
"node-fetch": "^3.3.2"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"nodemon": "^3.0.2"
|
||||||
|
}
|
||||||
|
}
|
||||||
126
src/commands/minecraft.js
Normal file
126
src/commands/minecraft.js
Normal file
@ -0,0 +1,126 @@
|
|||||||
|
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');
|
||||||
|
const WhitelistManager = require('../utils/whitelistManager');
|
||||||
|
const MinecraftServerUtil = require('../utils/minecraftServer');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('minecraft')
|
||||||
|
.setDescription('Commandes de gestion du serveur Minecraft')
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('list')
|
||||||
|
.setDescription('Affiche la liste des joueurs whitelistés')
|
||||||
|
)
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('add')
|
||||||
|
.setDescription('Ajoute un joueur à la whitelist')
|
||||||
|
.addStringOption(option =>
|
||||||
|
option
|
||||||
|
.setName('pseudo')
|
||||||
|
.setDescription('Le pseudo Minecraft du joueur à ajouter')
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('remove')
|
||||||
|
.setDescription('Retire un joueur de la whitelist')
|
||||||
|
.addStringOption(option =>
|
||||||
|
option
|
||||||
|
.setName('pseudo')
|
||||||
|
.setDescription('Le pseudo Minecraft du joueur à retirer')
|
||||||
|
.setRequired(true)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
.addSubcommand(subcommand =>
|
||||||
|
subcommand
|
||||||
|
.setName('status')
|
||||||
|
.setDescription('Affiche le status du serveur Minecraft')
|
||||||
|
),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
// Vérifier si l'utilisateur est le propriétaire
|
||||||
|
if (interaction.user.id !== process.env.OWNER_ID) {
|
||||||
|
return await interaction.reply({
|
||||||
|
content: '❌ Vous n\'avez pas la permission d\'utiliser cette commande.',
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const subcommand = interaction.options.getSubcommand();
|
||||||
|
const whitelistManager = new WhitelistManager();
|
||||||
|
const serverUtil = new MinecraftServerUtil();
|
||||||
|
|
||||||
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
try {
|
||||||
|
switch (subcommand) {
|
||||||
|
case 'list': {
|
||||||
|
const players = await whitelistManager.getWhitelistPlayers();
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('📋 Liste des joueurs whitelistés')
|
||||||
|
.setColor('#0099FF')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (players.length === 0) {
|
||||||
|
embed.setDescription('Aucun joueur dans la whitelist.');
|
||||||
|
} else {
|
||||||
|
const playerList = players.join('\n');
|
||||||
|
embed.setDescription(`**${players.length} joueur(s) whitelisté(s) :**\n\`\`\`\n${playerList}\n\`\`\``);
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [embed] });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'add': {
|
||||||
|
const pseudo = interaction.options.getString('pseudo');
|
||||||
|
const result = await whitelistManager.addPlayer(pseudo);
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle(result.success ? '✅ Joueur ajouté' : '❌ Erreur')
|
||||||
|
.setDescription(result.message)
|
||||||
|
.setColor(result.success ? '#00FF00' : '#FF0000')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [embed] });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'remove': {
|
||||||
|
const pseudo = interaction.options.getString('pseudo');
|
||||||
|
const result = await whitelistManager.removePlayer(pseudo);
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle(result.success ? '✅ Joueur retiré' : '❌ Erreur')
|
||||||
|
.setDescription(result.message)
|
||||||
|
.setColor(result.success ? '#00FF00' : '#FF0000')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [embed] });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'status': {
|
||||||
|
const statusData = await serverUtil.getServerStatus();
|
||||||
|
const embed = serverUtil.formatStatusEmbed(statusData);
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [embed] });
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur dans la commande minecraft:', error);
|
||||||
|
|
||||||
|
const errorEmbed = new EmbedBuilder()
|
||||||
|
.setTitle('❌ Erreur')
|
||||||
|
.setDescription('Une erreur est survenue lors de l\'exécution de la commande.')
|
||||||
|
.setColor('#FF0000')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
await interaction.editReply({ embeds: [errorEmbed] });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
40
src/commands/setup-access.js
Normal file
40
src/commands/setup-access.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
const { SlashCommandBuilder } = require('discord.js');
|
||||||
|
const AccessRequestManager = require('../utils/accessRequestManager');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
data: new SlashCommandBuilder()
|
||||||
|
.setName('setup-access')
|
||||||
|
.setDescription('Envoie le message de demande d\'accès dans le canal actuel'),
|
||||||
|
|
||||||
|
async execute(interaction) {
|
||||||
|
// Vérifier si l'utilisateur est le propriétaire
|
||||||
|
if (interaction.user.id !== process.env.OWNER_ID) {
|
||||||
|
return await interaction.reply({
|
||||||
|
content: '❌ Vous n\'avez pas la permission d\'utiliser cette commande.',
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const embed = AccessRequestManager.createRequestEmbed();
|
||||||
|
const button = AccessRequestManager.createRequestButton();
|
||||||
|
|
||||||
|
await interaction.reply({
|
||||||
|
content: '✅ Message de demande d\'accès envoyé !',
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
|
||||||
|
await interaction.followUp({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [button]
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de l\'envoi du message de demande d\'accès:', error);
|
||||||
|
await interaction.reply({
|
||||||
|
content: '❌ Erreur lors de l\'envoi du message.',
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
47
src/events/ready.js
Normal file
47
src/events/ready.js
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
const { REST, Routes } = require('discord.js');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'ready',
|
||||||
|
once: true,
|
||||||
|
async execute(client) {
|
||||||
|
console.log(`🚀 ${client.user.tag} est maintenant en ligne !`);
|
||||||
|
console.log(`📊 Connecté à ${client.guilds.cache.size} serveur(s)`);
|
||||||
|
console.log(`👥 ${client.users.cache.size} utilisateur(s) dans le cache`);
|
||||||
|
|
||||||
|
// Enregistrer les commandes slash
|
||||||
|
try {
|
||||||
|
console.log('🔄 Début de l\'actualisation des commandes slash...');
|
||||||
|
|
||||||
|
const commands = [];
|
||||||
|
for (const command of client.commands.values()) {
|
||||||
|
commands.push(command.data.toJSON());
|
||||||
|
}
|
||||||
|
|
||||||
|
const rest = new REST().setToken(process.env.TOKEN);
|
||||||
|
|
||||||
|
// Pour un serveur spécifique (plus rapide pendant le développement)
|
||||||
|
if (process.env.SUPPORT_SERVER_ID) {
|
||||||
|
await rest.put(
|
||||||
|
Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.SUPPORT_SERVER_ID),
|
||||||
|
{ body: commands }
|
||||||
|
);
|
||||||
|
console.log(`✅ ${commands.length} commande(s) slash enregistrée(s) pour le serveur de support.`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Pour tous les serveurs (global) - décommentez si nécessaire
|
||||||
|
/*
|
||||||
|
await rest.put(
|
||||||
|
Routes.applicationCommands(process.env.CLIENT_ID),
|
||||||
|
{ body: commands }
|
||||||
|
);
|
||||||
|
console.log(`✅ ${commands.length} commande(s) slash enregistrée(s) globalement.`);
|
||||||
|
*/
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Erreur lors de l\'enregistrement des commandes slash:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Définir le statut du bot
|
||||||
|
client.user.setActivity(`${process.env.MINECRAFT_SERVER_IP}`, { type: 'WATCHING' });
|
||||||
|
},
|
||||||
|
};
|
||||||
26
src/handlers/commandHandler.js
Normal file
26
src/handlers/commandHandler.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
const { Collection } = require('discord.js');
|
||||||
|
|
||||||
|
async function loadCommands(client) {
|
||||||
|
client.commands = new Collection();
|
||||||
|
|
||||||
|
const commandsPath = path.join(__dirname, '../commands');
|
||||||
|
const commandFiles = fs.readdirSync(commandsPath).filter(file => file.endsWith('.js'));
|
||||||
|
|
||||||
|
for (const file of commandFiles) {
|
||||||
|
const filePath = path.join(commandsPath, file);
|
||||||
|
const command = require(filePath);
|
||||||
|
|
||||||
|
if ('data' in command && 'execute' in command) {
|
||||||
|
client.commands.set(command.data.name, command);
|
||||||
|
console.log(`✅ Commande chargée: ${command.data.name}`);
|
||||||
|
} else {
|
||||||
|
console.log(`⚠️ La commande ${filePath} n'a pas les propriétés "data" ou "execute" requises.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`📝 ${commandFiles.length} commande(s) chargée(s).`);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { loadCommands };
|
||||||
35
src/handlers/eventHandler.js
Normal file
35
src/handlers/eventHandler.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
const fs = require('fs');
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
async function loadEvents(client) {
|
||||||
|
const eventsPath = path.join(__dirname, '../events');
|
||||||
|
|
||||||
|
// Créer le dossier events s'il n'existe pas
|
||||||
|
if (!fs.existsSync(eventsPath)) {
|
||||||
|
fs.mkdirSync(eventsPath, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const eventFiles = fs.readdirSync(eventsPath).filter(file => file.endsWith('.js'));
|
||||||
|
|
||||||
|
for (const file of eventFiles) {
|
||||||
|
const filePath = path.join(eventsPath, file);
|
||||||
|
const event = require(filePath);
|
||||||
|
|
||||||
|
if (event.once) {
|
||||||
|
client.once(event.name, (...args) => event.execute(...args));
|
||||||
|
} else {
|
||||||
|
client.on(event.name, (...args) => event.execute(...args));
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`✅ Événement chargé: ${event.name}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Charger directement l'handler d'interactions
|
||||||
|
const interactionHandler = require('./interactionHandler');
|
||||||
|
client.on('interactionCreate', (...args) => interactionHandler.execute(...args));
|
||||||
|
console.log('✅ Handler d\'interactions chargé');
|
||||||
|
|
||||||
|
console.log(`📝 ${eventFiles.length + 1} événement(s) chargé(s).`);
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = { loadEvents };
|
||||||
191
src/handlers/interactionHandler.js
Normal file
191
src/handlers/interactionHandler.js
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
const { ModalBuilder, TextInputBuilder, TextInputStyle, ActionRowBuilder } = require('discord.js');
|
||||||
|
const AccessRequestManager = require('../utils/accessRequestManager');
|
||||||
|
const WhitelistManager = require('../utils/whitelistManager');
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
name: 'interactionCreate',
|
||||||
|
async execute(interaction) {
|
||||||
|
if (interaction.isChatInputCommand()) {
|
||||||
|
const command = interaction.client.commands.get(interaction.commandName);
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
console.error(`Aucune commande correspondant à ${interaction.commandName} n'a été trouvée.`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await command.execute(interaction);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de l\'exécution de la commande:', error);
|
||||||
|
const reply = {
|
||||||
|
content: 'Il y a eu une erreur lors de l\'exécution de cette commande !',
|
||||||
|
ephemeral: true
|
||||||
|
};
|
||||||
|
if (interaction.replied || interaction.deferred) {
|
||||||
|
await interaction.followUp(reply);
|
||||||
|
} else {
|
||||||
|
await interaction.reply(reply);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (interaction.isButton()) {
|
||||||
|
await handleButtonInteraction(interaction);
|
||||||
|
} else if (interaction.isModalSubmit()) {
|
||||||
|
await handleModalSubmit(interaction);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
async function handleButtonInteraction(interaction) {
|
||||||
|
if (interaction.customId === 'request_access') {
|
||||||
|
// Créer le modal pour demander le pseudo Minecraft
|
||||||
|
const modal = new ModalBuilder()
|
||||||
|
.setCustomId('minecraft_access_modal')
|
||||||
|
.setTitle('Demande d\'accès Minecraft');
|
||||||
|
|
||||||
|
const usernameInput = new TextInputBuilder()
|
||||||
|
.setCustomId('minecraft_username')
|
||||||
|
.setLabel('Votre pseudo Minecraft')
|
||||||
|
.setStyle(TextInputStyle.Short)
|
||||||
|
.setPlaceholder('Entrez votre pseudo Minecraft exact...')
|
||||||
|
.setRequired(true)
|
||||||
|
.setMaxLength(16)
|
||||||
|
.setMinLength(3);
|
||||||
|
|
||||||
|
const firstActionRow = new ActionRowBuilder().addComponents(usernameInput);
|
||||||
|
modal.addComponents(firstActionRow);
|
||||||
|
|
||||||
|
await interaction.showModal(modal);
|
||||||
|
} else if (interaction.customId.startsWith('accept_request_') || interaction.customId.startsWith('deny_request_')) {
|
||||||
|
await handleStaffResponse(interaction);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleModalSubmit(interaction) {
|
||||||
|
if (interaction.customId === 'minecraft_access_modal') {
|
||||||
|
const username = interaction.fields.getTextInputValue('minecraft_username');
|
||||||
|
|
||||||
|
await interaction.deferReply({ ephemeral: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Vérifier si le joueur est déjà whitelisté
|
||||||
|
const whitelistManager = new WhitelistManager();
|
||||||
|
const isAlreadyWhitelisted = await whitelistManager.isPlayerWhitelisted(username);
|
||||||
|
|
||||||
|
// Envoyer la demande au canal du staff
|
||||||
|
const staffChannel = interaction.client.channels.cache.get(process.env.CHANNEL_ACCESS_STAFF_REQUESTS_ID);
|
||||||
|
|
||||||
|
if (!staffChannel) {
|
||||||
|
return await interaction.editReply({
|
||||||
|
content: '❌ Erreur : Canal du staff introuvable. Contactez un administrateur.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = AccessRequestManager.createStaffEmbed(interaction.user, username, isAlreadyWhitelisted);
|
||||||
|
const buttons = AccessRequestManager.createStaffButtons(interaction.user.id, username, isAlreadyWhitelisted);
|
||||||
|
|
||||||
|
await staffChannel.send({
|
||||||
|
embeds: [embed],
|
||||||
|
components: [buttons]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Répondre à l'utilisateur
|
||||||
|
let responseMessage = '✅ Votre demande d\'accès a été envoyée à l\'équipe administrative !';
|
||||||
|
|
||||||
|
if (isAlreadyWhitelisted) {
|
||||||
|
responseMessage += '\n\n⚠️ **Note :** Vous êtes déjà dans la whitelist du serveur.';
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
content: responseMessage
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors du traitement de la demande d\'accès:', error);
|
||||||
|
await interaction.editReply({
|
||||||
|
content: '❌ Une erreur est survenue lors du traitement de votre demande. Veuillez réessayer.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function handleStaffResponse(interaction) {
|
||||||
|
// Vérifier si l'utilisateur a le rôle admin
|
||||||
|
if (!interaction.member.roles.cache.has(process.env.ROLE_ADMIN_ID)) {
|
||||||
|
return await interaction.reply({
|
||||||
|
content: '❌ Vous n\'avez pas la permission de traiter les demandes d\'accès.',
|
||||||
|
ephemeral: true
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const [action, , userId, username] = interaction.customId.split('_');
|
||||||
|
const isAccepted = action === 'accept';
|
||||||
|
|
||||||
|
await interaction.deferReply({ ephemeral: true });
|
||||||
|
|
||||||
|
try {
|
||||||
|
const whitelistManager = new WhitelistManager();
|
||||||
|
let result = { success: true, message: '' };
|
||||||
|
|
||||||
|
if (isAccepted) {
|
||||||
|
// Ajouter le joueur à la whitelist
|
||||||
|
result = await whitelistManager.addPlayer(username);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Envoyer une réponse à l'utilisateur qui a fait la demande
|
||||||
|
try {
|
||||||
|
const user = await interaction.client.users.fetch(userId);
|
||||||
|
const responseEmbed = AccessRequestManager.createResponseEmbed(
|
||||||
|
isAccepted && result.success,
|
||||||
|
username,
|
||||||
|
isAccepted && !result.success ? result.message : null
|
||||||
|
);
|
||||||
|
|
||||||
|
await user.send({ embeds: [responseEmbed] });
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Impossible d\'envoyer un MP à l\'utilisateur:', error);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mettre à jour le message original
|
||||||
|
const originalEmbed = interaction.message.embeds[0];
|
||||||
|
const updatedEmbed = {
|
||||||
|
...originalEmbed.toJSON(),
|
||||||
|
color: isAccepted && result.success ? 0x00FF00 : 0xFF0000,
|
||||||
|
fields: [
|
||||||
|
...originalEmbed.fields,
|
||||||
|
{
|
||||||
|
name: isAccepted ? '✅ Accepté par' : '❌ Refusé par',
|
||||||
|
value: `${interaction.user.tag} (<t:${Math.floor(Date.now() / 1000)}:R>)`,
|
||||||
|
inline: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
if (isAccepted && !result.success) {
|
||||||
|
updatedEmbed.fields.push({
|
||||||
|
name: '⚠️ Erreur',
|
||||||
|
value: result.message,
|
||||||
|
inline: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
await interaction.message.edit({
|
||||||
|
embeds: [updatedEmbed],
|
||||||
|
components: [] // Retirer les boutons
|
||||||
|
});
|
||||||
|
|
||||||
|
// Répondre au staff member
|
||||||
|
const statusMessage = isAccepted
|
||||||
|
? (result.success ? `✅ Demande acceptée et ${username} ajouté à la whitelist.` : `❌ Erreur lors de l'ajout : ${result.message}`)
|
||||||
|
: `❌ Demande refusée pour ${username}.`;
|
||||||
|
|
||||||
|
await interaction.editReply({
|
||||||
|
content: statusMessage
|
||||||
|
});
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors du traitement de la réponse du staff:', error);
|
||||||
|
await interaction.editReply({
|
||||||
|
content: '❌ Une erreur est survenue lors du traitement de la demande.'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
110
src/utils/accessRequestManager.js
Normal file
110
src/utils/accessRequestManager.js
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle } = require('discord.js');
|
||||||
|
|
||||||
|
class AccessRequestManager {
|
||||||
|
static createRequestEmbed() {
|
||||||
|
return new EmbedBuilder()
|
||||||
|
.setTitle('🎮 Accès au serveur Minecraft')
|
||||||
|
.setDescription(
|
||||||
|
'Bienvenue ! Pour rejoindre notre serveur Minecraft, vous devez être ajouté à la whitelist.\n\n' +
|
||||||
|
'**Comment procéder :**\n' +
|
||||||
|
'1️⃣ Cliquez sur le bouton "Demander l\'accès" ci-dessous\n' +
|
||||||
|
'2️⃣ Entrez votre pseudo Minecraft exact\n' +
|
||||||
|
'3️⃣ Attendez l\'approbation d\'un administrateur\n\n' +
|
||||||
|
'**Informations importantes :**\n' +
|
||||||
|
'• Votre pseudo doit être valide et correspondre à votre compte Minecraft\n' +
|
||||||
|
'• Si vous êtes déjà whitelisté, le système vous en informera\n' +
|
||||||
|
'• Les demandes sont traitées par l\'équipe administrative\n\n' +
|
||||||
|
`**Adresse du serveur :** \`${process.env.MINECRAFT_SERVER_IP}\``
|
||||||
|
)
|
||||||
|
.setColor('#00FF00')
|
||||||
|
.setThumbnail('https://i.imgur.com/YSO5z0H.png') // Image Minecraft
|
||||||
|
.setFooter({ text: 'Serveur Minecraft • Demande d\'accès' })
|
||||||
|
.setTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
static createRequestButton() {
|
||||||
|
return new ActionRowBuilder()
|
||||||
|
.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId('request_access')
|
||||||
|
.setLabel('Demander l\'accès')
|
||||||
|
.setStyle(ButtonStyle.Primary)
|
||||||
|
.setEmoji('🎮')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
static createStaffEmbed(user, username, isAlreadyWhitelisted = false) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('📋 Nouvelle demande d\'accès Minecraft')
|
||||||
|
.setDescription(`${user} souhaite rejoindre le serveur Minecraft.`)
|
||||||
|
.addFields(
|
||||||
|
{ name: '👤 Utilisateur Discord', value: `${user.tag} (${user.id})`, inline: true },
|
||||||
|
{ name: '🎮 Pseudo Minecraft', value: `\`${username}\``, inline: true },
|
||||||
|
{ name: '📅 Date de la demande', value: `<t:${Math.floor(Date.now() / 1000)}:F>`, inline: false }
|
||||||
|
)
|
||||||
|
.setThumbnail(user.displayAvatarURL({ dynamic: true }))
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (isAlreadyWhitelisted) {
|
||||||
|
embed.setColor('#FFA500')
|
||||||
|
.addFields({ name: '⚠️ Avertissement', value: 'Ce joueur est déjà dans la whitelist !', inline: false });
|
||||||
|
} else {
|
||||||
|
embed.setColor('#0099FF');
|
||||||
|
}
|
||||||
|
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createStaffButtons(userId, username, isAlreadyWhitelisted = false) {
|
||||||
|
const row = new ActionRowBuilder();
|
||||||
|
|
||||||
|
if (!isAlreadyWhitelisted) {
|
||||||
|
row.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`accept_request_${userId}_${username}`)
|
||||||
|
.setLabel('Accepter')
|
||||||
|
.setStyle(ButtonStyle.Success)
|
||||||
|
.setEmoji('✅')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
row.addComponents(
|
||||||
|
new ButtonBuilder()
|
||||||
|
.setCustomId(`deny_request_${userId}_${username}`)
|
||||||
|
.setLabel('Refuser')
|
||||||
|
.setStyle(ButtonStyle.Danger)
|
||||||
|
.setEmoji('❌')
|
||||||
|
);
|
||||||
|
|
||||||
|
return row;
|
||||||
|
}
|
||||||
|
|
||||||
|
static createResponseEmbed(accepted, username, reason = null) {
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (accepted) {
|
||||||
|
embed.setTitle('✅ Demande acceptée !')
|
||||||
|
.setDescription(
|
||||||
|
`Félicitations ! Votre demande d'accès au serveur Minecraft a été **acceptée**.\n\n` +
|
||||||
|
`**Pseudo ajouté :** \`${username}\`\n` +
|
||||||
|
`**Adresse du serveur :** \`${process.env.MINECRAFT_SERVER_IP}\`\n\n` +
|
||||||
|
`Vous pouvez maintenant vous connecter au serveur !`
|
||||||
|
)
|
||||||
|
.setColor('#00FF00');
|
||||||
|
} else {
|
||||||
|
embed.setTitle('❌ Demande refusée')
|
||||||
|
.setDescription(
|
||||||
|
`Votre demande d'accès au serveur Minecraft a été **refusée**.\n\n` +
|
||||||
|
`**Pseudo demandé :** \`${username}\`\n` +
|
||||||
|
(reason ? `**Raison :** ${reason}\n\n` : '') +
|
||||||
|
`Vous pouvez faire une nouvelle demande si nécessaire.`
|
||||||
|
)
|
||||||
|
.setColor('#FF0000');
|
||||||
|
}
|
||||||
|
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = AccessRequestManager;
|
||||||
82
src/utils/minecraftServer.js
Normal file
82
src/utils/minecraftServer.js
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
const { status } = require('minecraft-server-util');
|
||||||
|
|
||||||
|
class MinecraftServerUtil {
|
||||||
|
constructor() {
|
||||||
|
this.serverIP = process.env.MINECRAFT_SERVER_IP;
|
||||||
|
this.host = this.serverIP.split(':')[0];
|
||||||
|
this.port = parseInt(this.serverIP.split(':')[1]) || 25565;
|
||||||
|
}
|
||||||
|
|
||||||
|
async getServerStatus() {
|
||||||
|
try {
|
||||||
|
const result = await status(this.host, this.port);
|
||||||
|
|
||||||
|
return {
|
||||||
|
online: true,
|
||||||
|
version: result.version.name,
|
||||||
|
protocol: result.version.protocol,
|
||||||
|
players: {
|
||||||
|
online: result.players.online,
|
||||||
|
max: result.players.max,
|
||||||
|
list: result.players.sample || []
|
||||||
|
},
|
||||||
|
description: result.description.text || result.description,
|
||||||
|
latency: result.roundTripLatency,
|
||||||
|
favicon: result.favicon
|
||||||
|
};
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la vérification du serveur:', error);
|
||||||
|
return {
|
||||||
|
online: false,
|
||||||
|
error: error.message
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async isServerOnline() {
|
||||||
|
const status = await this.getServerStatus();
|
||||||
|
return status.online;
|
||||||
|
}
|
||||||
|
|
||||||
|
formatStatusEmbed(statusData) {
|
||||||
|
const { EmbedBuilder } = require('discord.js');
|
||||||
|
|
||||||
|
if (!statusData.online) {
|
||||||
|
return new EmbedBuilder()
|
||||||
|
.setTitle('🔴 Serveur Minecraft - Hors ligne')
|
||||||
|
.setDescription(`Le serveur \`${this.serverIP}\` est actuellement hors ligne.`)
|
||||||
|
.addFields(
|
||||||
|
{ name: 'Erreur', value: statusData.error || 'Serveur inaccessible', inline: true }
|
||||||
|
)
|
||||||
|
.setColor('#FF0000')
|
||||||
|
.setTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
const embed = new EmbedBuilder()
|
||||||
|
.setTitle('🟢 Serveur Minecraft - En ligne')
|
||||||
|
.setDescription(`Le serveur \`${this.serverIP}\` est en ligne !`)
|
||||||
|
.addFields(
|
||||||
|
{ name: '👥 Joueurs', value: `${statusData.players.online}/${statusData.players.max}`, inline: true },
|
||||||
|
{ name: '📋 Version', value: statusData.version, inline: true },
|
||||||
|
{ name: '📡 Latence', value: `${statusData.latency}ms`, inline: true }
|
||||||
|
)
|
||||||
|
.setColor('#00FF00')
|
||||||
|
.setTimestamp();
|
||||||
|
|
||||||
|
if (statusData.description) {
|
||||||
|
embed.addFields({ name: '📝 Description', value: statusData.description, inline: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statusData.players.list && statusData.players.list.length > 0) {
|
||||||
|
const playerList = statusData.players.list
|
||||||
|
.slice(0, 10) // Limiter à 10 joueurs
|
||||||
|
.map(player => player.name)
|
||||||
|
.join(', ');
|
||||||
|
embed.addFields({ name: '🎮 Joueurs connectés', value: playerList, inline: false });
|
||||||
|
}
|
||||||
|
|
||||||
|
return embed;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = MinecraftServerUtil;
|
||||||
119
src/utils/whitelistManager.js
Normal file
119
src/utils/whitelistManager.js
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
const fs = require('fs').promises;
|
||||||
|
const path = require('path');
|
||||||
|
|
||||||
|
class WhitelistManager {
|
||||||
|
constructor() {
|
||||||
|
this.whitelistPath = process.env.MINECRAFT_WHITELIST_PATH;
|
||||||
|
}
|
||||||
|
|
||||||
|
async readWhitelist() {
|
||||||
|
try {
|
||||||
|
const data = await fs.readFile(this.whitelistPath, 'utf8');
|
||||||
|
return JSON.parse(data);
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la lecture de la whitelist:', error);
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async writeWhitelist(whitelist) {
|
||||||
|
try {
|
||||||
|
await fs.writeFile(this.whitelistPath, JSON.stringify(whitelist, null, 2));
|
||||||
|
return true;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de l\'écriture de la whitelist:', error);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async isPlayerWhitelisted(username) {
|
||||||
|
const whitelist = await this.readWhitelist();
|
||||||
|
return whitelist.some(player =>
|
||||||
|
player.name.toLowerCase() === username.toLowerCase()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
async addPlayer(username, uuid = null) {
|
||||||
|
try {
|
||||||
|
const whitelist = await this.readWhitelist();
|
||||||
|
|
||||||
|
// Vérifier si le joueur existe déjà
|
||||||
|
if (await this.isPlayerWhitelisted(username)) {
|
||||||
|
return { success: false, message: 'Le joueur est déjà dans la whitelist.' };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si pas d'UUID fourni, essayer de le récupérer via l'API Mojang
|
||||||
|
if (!uuid) {
|
||||||
|
uuid = await this.getUUIDFromUsername(username);
|
||||||
|
if (!uuid) {
|
||||||
|
return { success: false, message: 'Impossible de trouver l\'UUID pour ce joueur.' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ajouter le joueur
|
||||||
|
whitelist.push({
|
||||||
|
uuid: uuid,
|
||||||
|
name: username
|
||||||
|
});
|
||||||
|
|
||||||
|
const success = await this.writeWhitelist(whitelist);
|
||||||
|
if (success) {
|
||||||
|
return { success: true, message: `${username} a été ajouté à la whitelist.` };
|
||||||
|
} else {
|
||||||
|
return { success: false, message: 'Erreur lors de l\'ajout du joueur.' };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de l\'ajout du joueur:', error);
|
||||||
|
return { success: false, message: 'Erreur interne lors de l\'ajout du joueur.' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async removePlayer(username) {
|
||||||
|
try {
|
||||||
|
const whitelist = await this.readWhitelist();
|
||||||
|
const initialLength = whitelist.length;
|
||||||
|
|
||||||
|
const newWhitelist = whitelist.filter(player =>
|
||||||
|
player.name.toLowerCase() !== username.toLowerCase()
|
||||||
|
);
|
||||||
|
|
||||||
|
if (newWhitelist.length === initialLength) {
|
||||||
|
return { success: false, message: 'Le joueur n\'est pas dans la whitelist.' };
|
||||||
|
}
|
||||||
|
|
||||||
|
const success = await this.writeWhitelist(newWhitelist);
|
||||||
|
if (success) {
|
||||||
|
return { success: true, message: `${username} a été retiré de la whitelist.` };
|
||||||
|
} else {
|
||||||
|
return { success: false, message: 'Erreur lors de la suppression du joueur.' };
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la suppression du joueur:', error);
|
||||||
|
return { success: false, message: 'Erreur interne lors de la suppression du joueur.' };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async getWhitelistPlayers() {
|
||||||
|
const whitelist = await this.readWhitelist();
|
||||||
|
return whitelist.map(player => player.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUUIDFromUsername(username) {
|
||||||
|
try {
|
||||||
|
const fetch = (await import('node-fetch')).default;
|
||||||
|
const response = await fetch(`https://api.mojang.com/users/profiles/minecraft/${username}`);
|
||||||
|
|
||||||
|
if (!response.ok) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await response.json();
|
||||||
|
return data.id;
|
||||||
|
} catch (error) {
|
||||||
|
console.error('Erreur lors de la récupération de l\'UUID:', error);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = WhitelistManager;
|
||||||
33
start.js
Normal file
33
start.js
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
require('dotenv').config();
|
||||||
|
const { Client, GatewayIntentBits } = require('discord.js');
|
||||||
|
const { loadCommands } = require('./src/handlers/commandHandler');
|
||||||
|
const { loadEvents } = require('./src/handlers/eventHandler');
|
||||||
|
|
||||||
|
const client = new Client({
|
||||||
|
intents: [
|
||||||
|
GatewayIntentBits.Guilds,
|
||||||
|
GatewayIntentBits.GuildMessages,
|
||||||
|
GatewayIntentBits.MessageContent,
|
||||||
|
GatewayIntentBits.GuildMembers
|
||||||
|
]
|
||||||
|
});
|
||||||
|
|
||||||
|
async function startBot() {
|
||||||
|
try {
|
||||||
|
console.log('🚀 Démarrage du bot...');
|
||||||
|
|
||||||
|
// Charger les commandes et événements
|
||||||
|
await loadCommands(client);
|
||||||
|
await loadEvents(client);
|
||||||
|
|
||||||
|
// Connexion du bot
|
||||||
|
await client.login(process.env.TOKEN);
|
||||||
|
|
||||||
|
console.log('✅ Bot connecté avec succès !');
|
||||||
|
} catch (error) {
|
||||||
|
console.error('❌ Erreur lors du démarrage du bot:', error);
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
startBot();
|
||||||
Loading…
Reference in New Issue
Block a user