Add files via upload
This commit is contained in:
38
commands/dev/reload.js
Normal file
38
commands/dev/reload.js
Normal file
@@ -0,0 +1,38 @@
|
||||
const { SlashCommandBuilder, PermissionFlagsBits } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
category: 'dev',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('reload')
|
||||
.setDescription('Reloads a command.')
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
|
||||
.addStringOption(option =>
|
||||
option.setName('command')
|
||||
.setDescription('The command to reload.')
|
||||
.setRequired(true)),
|
||||
async execute(interaction) {
|
||||
// Vérification côté bot pour être sûr
|
||||
if (!interaction.member.permissions.has(PermissionFlagsBits.Administrator)) {
|
||||
return interaction.reply({ content: '❌ Only administrators can use this command.', ephemeral: true });
|
||||
}
|
||||
|
||||
|
||||
const commandName = interaction.options.getString('command', true).toLowerCase();
|
||||
const command = interaction.client.commands.get(commandName);
|
||||
|
||||
if (!command) {
|
||||
return interaction.reply({ content: `There is no command with name \`${commandName}\`!`, ephemeral: true });
|
||||
}
|
||||
|
||||
delete require.cache[require.resolve(`../${command.category}/${command.data.name}.js`)];
|
||||
|
||||
try {
|
||||
const newCommand = require(`../${command.category}/${command.data.name}.js`);
|
||||
interaction.client.commands.set(newCommand.data.name, newCommand);
|
||||
await interaction.reply({ content: `✅ Command \`${newCommand.data.name}\` was reloaded!`, ephemeral: true });
|
||||
} catch (error) {
|
||||
console.error(error);
|
||||
await interaction.reply({ content: `❌ Error while reloading \`${command.data.name}\`:\n\`${error.message}\``, ephemeral: true });
|
||||
}
|
||||
},
|
||||
};
|
||||
95
commands/moderation/ban.js
Normal file
95
commands/moderation/ban.js
Normal file
@@ -0,0 +1,95 @@
|
||||
const { SlashCommandBuilder, PermissionFlagsBits, EmbedBuilder } = require('discord.js');
|
||||
const db = require('../../functions/database/db.js'); // instance mysql2/promise
|
||||
|
||||
module.exports = {
|
||||
category: 'moderation',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ban')
|
||||
.setDescription('Select a member and ban them.')
|
||||
.addUserOption(option =>
|
||||
option.setName('target')
|
||||
.setDescription('The member to ban')
|
||||
.setRequired(true))
|
||||
.addStringOption(option =>
|
||||
option.setName('reason')
|
||||
.setDescription('Reason')
|
||||
.setRequired(false))
|
||||
.addStringOption(option =>
|
||||
option.setName('duration')
|
||||
.setDescription('Ban duration (ex: 1h, 2d, leave empty for permanent)')
|
||||
.setRequired(false))
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers),
|
||||
|
||||
async execute(interaction) {
|
||||
const target = interaction.options.getUser('target');
|
||||
const reason = interaction.options.getString('reason') || 'No reason provided';
|
||||
const durationInput = interaction.options.getString('duration');
|
||||
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
if (!target) return interaction.editReply({ content: 'No user specified!' });
|
||||
await interaction.guild.bans.create(target.id, { reason: `Banned by ${interaction.user.tag}: ${reason}` });
|
||||
|
||||
let type = 'Permanent';
|
||||
let unbanDate = null;
|
||||
|
||||
if (durationInput) {
|
||||
const regex = /^(\d+)([smhd])$/;
|
||||
const match = durationInput.match(regex);
|
||||
if (match) {
|
||||
const value = parseInt(match[1]);
|
||||
const unit = match[2];
|
||||
let multiplier = 1000;
|
||||
if (unit === 'm') multiplier *= 60;
|
||||
if (unit === 'h') multiplier *= 60 * 60;
|
||||
if (unit === 'd') multiplier *= 60 * 60 * 24;
|
||||
unbanDate = Date.now() + value * multiplier;
|
||||
type = 'Temporary';
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
// Bannissement
|
||||
interaction.guild.bans.create(target.id, { reason: `Banned by ${interaction.user.tag}: ${reason}` });
|
||||
|
||||
// Stockage dans MySQL (bans)
|
||||
await db.query(
|
||||
`INSERT INTO bans (userId, reason, modId, timestamp, type, unbanDate)
|
||||
VALUES (?, ?, ?, ?, ?, ?)
|
||||
ON DUPLICATE KEY UPDATE reason=VALUES(reason), modId=VALUES(modId), timestamp=VALUES(timestamp), type=VALUES(type), unbanDate=VALUES(unbanDate)`,
|
||||
[target.id, reason, interaction.user.id, Date.now(), type, unbanDate]
|
||||
);
|
||||
|
||||
// Stockage dans logs (ajout guildId)
|
||||
await db.query(
|
||||
`INSERT INTO logs (userId, userTag, modId, modTag, action, reason, type, guildId, timestamp)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[target.id, target.tag, interaction.user.id, interaction.user.tag, 'ban', reason, type, interaction.guild.id, Date.now()]
|
||||
);
|
||||
|
||||
await interaction.editReply(`✅ Successfully banned ${target.tag} (${type})`);
|
||||
|
||||
// Embed log
|
||||
const logChannel = interaction.guild.channels.cache.find(ch => ch.name === 'logs');
|
||||
if (logChannel) {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle('User Banned')
|
||||
.setColor('Red')
|
||||
.addFields(
|
||||
{ name: 'Banned User', value: `<@${target.id}> (${target.tag})`, inline: true },
|
||||
{ name: 'Banned By', value: `<@${interaction.user.id}> (${interaction.user.tag})`, inline: true },
|
||||
{ name: 'Reason', value: reason, inline: false },
|
||||
{ name: 'Type', value: type, inline: true },
|
||||
{ name: 'Date', value: new Date().toLocaleString(), inline: true },
|
||||
{ name: 'Guild', value: interaction.guild.name, inline: true }
|
||||
)
|
||||
.setTimestamp();
|
||||
logChannel.send({ embeds: [embed] });
|
||||
}
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
await interaction.editReply({ content: `❌ Failed to ban ${target.tag}` });
|
||||
}
|
||||
}
|
||||
};
|
||||
58
commands/moderation/casier.js
Normal file
58
commands/moderation/casier.js
Normal file
@@ -0,0 +1,58 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
||||
const db = require('../../functions/database/db.js'); // instance mysql2/promise
|
||||
|
||||
module.exports = {
|
||||
category: 'moderation',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('casier')
|
||||
.setDescription('Voir toutes les sanctions d’un membre.')
|
||||
.addUserOption(option =>
|
||||
option.setName('membre')
|
||||
.setDescription('Le membre dont tu veux voir le casier')
|
||||
.setRequired(true)),
|
||||
|
||||
async execute(interaction) {
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
const member = interaction.options.getUser('membre');
|
||||
|
||||
try {
|
||||
const [rows] = await db.query(
|
||||
'SELECT * FROM logs WHERE userId = ? ORDER BY timestamp DESC',
|
||||
[member.id]
|
||||
);
|
||||
|
||||
if (!rows.length) return interaction.editReply(`❌ ${member.tag} n’a aucune sanction.`);
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle(`Casier de ${member.tag}`)
|
||||
.setColor('Orange')
|
||||
.setTimestamp();
|
||||
|
||||
rows.forEach((row, index) => {
|
||||
const date = new Date(row.timestamp).toLocaleString();
|
||||
const actionCapitalized = row.action.charAt(0).toUpperCase() + row.action.slice(1); // Ban/Unban
|
||||
|
||||
// Récupère le nom du serveur via l'ID si présent
|
||||
const guildName = row.guildId
|
||||
? interaction.client.guilds.cache.get(row.guildId)?.name || 'Unknown Server'
|
||||
: 'Unknown Server';
|
||||
|
||||
embed.addFields({
|
||||
name: `#${index + 1} - ${actionCapitalized}`,
|
||||
value: `**Modérateur:** <@${row.modId}> (${row.modTag || 'N/A'})\n` +
|
||||
`**Raison:** ${row.reason || 'N/A'}\n` +
|
||||
`**Serveur:** ${guildName}\n` +
|
||||
`**Date:** ${date}`,
|
||||
inline: false
|
||||
});
|
||||
});
|
||||
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
await interaction.editReply('❌ Une erreur est survenue lors de la récupération du casier.');
|
||||
}
|
||||
},
|
||||
};
|
||||
65
commands/moderation/unban.js
Normal file
65
commands/moderation/unban.js
Normal file
@@ -0,0 +1,65 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');
|
||||
const db = require('../../functions/database/db.js');
|
||||
|
||||
module.exports = {
|
||||
category: 'moderation',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('unban')
|
||||
.setDescription('Unban a user by their ID or tag.')
|
||||
.addStringOption(option =>
|
||||
option.setName('user')
|
||||
.setDescription('The ID or tag (Username#1234) of the user to unban')
|
||||
.setRequired(true))
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.BanMembers),
|
||||
|
||||
async execute(interaction) {
|
||||
await interaction.deferReply({ ephemeral: true });
|
||||
|
||||
const input = interaction.options.getString('user').trim();
|
||||
|
||||
try {
|
||||
const bannedUsers = await interaction.guild.bans.fetch();
|
||||
const bannedUser = bannedUsers.find(b =>
|
||||
b.user.id === input || b.user.tag.toLowerCase() === input.toLowerCase()
|
||||
);
|
||||
if (!bannedUser) return interaction.editReply('❌ This user is not banned.');
|
||||
|
||||
// Récupération depuis MySQL
|
||||
const [rows] = await db.query('SELECT * FROM bans WHERE userId = ?', [bannedUser.user.id]);
|
||||
const banRecord = rows[0];
|
||||
|
||||
const reason = `Unbanned by ${interaction.user.tag}`;
|
||||
await interaction.guild.members.unban(bannedUser.user.id, reason);
|
||||
|
||||
if (banRecord) await db.query('DELETE FROM bans WHERE userId = ?', [bannedUser.user.id]);
|
||||
|
||||
await interaction.editReply(`✅ Successfully unbanned ${bannedUser.user.tag}`);
|
||||
|
||||
const logChannel = interaction.guild.channels.cache.find(ch => ch.name === 'logs');
|
||||
if (logChannel) {
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle('User Unbanned')
|
||||
.setColor('Green')
|
||||
.addFields(
|
||||
{ name: 'Membre Banni', value: `<@${bannedUser.user.id}> (${bannedUser.user.tag})`, inline: true },
|
||||
{ name: 'Modérateur', value: `<@${interaction.user.id}> (${interaction.user.tag})`, inline: true },
|
||||
{ name: 'Date', value: new Date().toLocaleString(), inline: true },
|
||||
{ name: 'Guild', value: interaction.guild.name, inline: true }
|
||||
)
|
||||
.setTimestamp();
|
||||
logChannel.send({ embeds: [embed] });
|
||||
}
|
||||
|
||||
// Log dans la DB avec guildId
|
||||
await db.query(
|
||||
`INSERT INTO logs (userId, userTag, modId, modTag, action, reason, type, guildId, timestamp)
|
||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`,
|
||||
[bannedUser.user.id, bannedUser.user.tag, interaction.user.id, interaction.user.tag, 'unban', reason, null, interaction.guild.id, Date.now()]
|
||||
);
|
||||
|
||||
} catch (err) {
|
||||
console.error(err);
|
||||
await interaction.editReply('❌ Failed to unban the user.');
|
||||
}
|
||||
}
|
||||
};
|
||||
23
commands/utility/ping.js
Normal file
23
commands/utility/ping.js
Normal file
@@ -0,0 +1,23 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
category: 'utility',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('ping')
|
||||
.setDescription('Replies with API latency and ICMP latency!'),
|
||||
async execute(interaction) {
|
||||
// --- API latency Discord ---
|
||||
const apiLatency = Math.round(interaction.client.ws.ping);
|
||||
|
||||
// --- Reply final ---
|
||||
const embed = new EmbedBuilder()
|
||||
.setColor('#00FFFF')
|
||||
.setTitle('🏓 Ping Status')
|
||||
.addFields(
|
||||
{ name: '🌐 API Latency', value: `${apiLatency}ms`, inline: true }
|
||||
)
|
||||
.setTimestamp();
|
||||
|
||||
await interaction.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user