Update Bot (j'ai plus le repo sur GitHub)
Qui c'est la conne qui a delete le repo sur GitHub? C'EST MOIIIII
This commit is contained in:
119
commands/info/adminprofil.js
Normal file
119
commands/info/adminprofil.js
Normal file
@@ -0,0 +1,119 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits, MessageFlags } = require('discord.js');
|
||||
const db = require('../../functions/database/db.js');
|
||||
const { colors } = require('../../utils/constants');
|
||||
const { sendLog } = require('../../utils/helpers');
|
||||
|
||||
module.exports = {
|
||||
category: 'info',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('adminprofil')
|
||||
.setDescription('Administrer les profils utilisateurs (Admin uniquement)')
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand
|
||||
.setName('reset')
|
||||
.setDescription('Réinitialiser le profil d\'un utilisateur')
|
||||
.addUserOption(option =>
|
||||
option.setName('user')
|
||||
.setDescription('L\'utilisateur dont tu veux réinitialiser le profil')
|
||||
.setRequired(true))
|
||||
.addStringOption(option =>
|
||||
option.setName('type')
|
||||
.setDescription('Ce qui doit être réinitialisé')
|
||||
.setRequired(true)
|
||||
.addChoices(
|
||||
{ name: 'Signature', value: 'signature' },
|
||||
{ name: 'Tout le profil', value: 'all' }
|
||||
))
|
||||
.addStringOption(option =>
|
||||
option.setName('reason')
|
||||
.setDescription('Raison de la réinitialisation')
|
||||
.setRequired(false))),
|
||||
async execute(interaction) {
|
||||
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||
|
||||
if (!interaction.member.permissions.has(PermissionFlagsBits.Administrator)) {
|
||||
return interaction.editReply({
|
||||
content: '❌ Tu n\'as pas la permission d\'utiliser cette commande. (Administrateur requis)'
|
||||
});
|
||||
}
|
||||
|
||||
const subcommand = interaction.options.getSubcommand();
|
||||
|
||||
if (subcommand === 'reset') {
|
||||
const target = interaction.options.getUser('user');
|
||||
const resetType = interaction.options.getString('type');
|
||||
const reason = interaction.options.getString('reason') || 'Aucune raison fournie';
|
||||
|
||||
if (!target) return interaction.editReply({ content: '❌ Aucun utilisateur spécifié !' });
|
||||
|
||||
try {
|
||||
const [profiles] = await db.query(
|
||||
'SELECT * FROM user_profiles WHERE userId = ? AND guildId = ?',
|
||||
[target.id, interaction.guild.id]
|
||||
);
|
||||
|
||||
if (profiles.length === 0) {
|
||||
return interaction.editReply({
|
||||
content: `❌ ${target.tag} n'a pas de profil à réinitialiser.`
|
||||
});
|
||||
}
|
||||
|
||||
if (resetType === 'signature') {
|
||||
await db.query(
|
||||
'UPDATE user_profiles SET signature = NULL, updatedAt = ? WHERE userId = ? AND guildId = ?',
|
||||
[Date.now(), target.id, interaction.guild.id]
|
||||
);
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle('✅ Signature Réinitialisée')
|
||||
.setColor(colors.success)
|
||||
.setDescription(`La signature de ${target.toString()} a été réinitialisée.`)
|
||||
.addFields(
|
||||
{ name: '👤 Utilisateur', value: `${target.tag}`, inline: true },
|
||||
{ name: '📝 Raison', value: reason, inline: false }
|
||||
)
|
||||
.setTimestamp();
|
||||
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
|
||||
} else if (resetType === 'all') {
|
||||
await db.query(
|
||||
'DELETE FROM user_profiles WHERE userId = ? AND guildId = ?',
|
||||
[target.id, interaction.guild.id]
|
||||
);
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle('✅ Profil Réinitialisé')
|
||||
.setColor(colors.success)
|
||||
.setDescription(`Le profil de ${target.toString()} a été complètement réinitialisé.`)
|
||||
.addFields(
|
||||
{ name: '👤 Utilisateur', value: `${target.tag}`, inline: true },
|
||||
{ name: '📝 Raison', value: reason, inline: false }
|
||||
)
|
||||
.setTimestamp();
|
||||
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
}
|
||||
|
||||
const logEmbed = new EmbedBuilder()
|
||||
.setTitle('🔄 Profil Réinitialisé (Admin)')
|
||||
.setColor(colors.warning)
|
||||
.setDescription(`Le profil de ${target.toString()} a été réinitialisé.`)
|
||||
.addFields(
|
||||
{ name: '👤 Utilisateur', value: `${target.tag} (${target.id})`, inline: true },
|
||||
{ name: '⚙️ Admin', value: `${interaction.user.tag} (${interaction.user.id})`, inline: true },
|
||||
{ name: '🔄 Type', value: resetType === 'signature' ? 'Signature' : 'Tout le profil', inline: true },
|
||||
{ name: '📝 Raison', value: reason, inline: false }
|
||||
)
|
||||
.setFooter({ text: 'France Femboy Bot • Administration' })
|
||||
.setTimestamp();
|
||||
|
||||
await sendLog(interaction.guild, { embeds: [logEmbed] });
|
||||
|
||||
} catch (err) {
|
||||
console.error('Erreur adminprofil:', err);
|
||||
await interaction.editReply({ content: `❌ Erreur: ${err.message}` });
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
43
commands/info/embed.js
Normal file
43
commands/info/embed.js
Normal file
@@ -0,0 +1,43 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');
|
||||
|
||||
module.exports = {
|
||||
category: 'info',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('embed')
|
||||
.setDescription('Créer un embed personnalisé.')
|
||||
.addStringOption(option =>
|
||||
option.setName('title')
|
||||
.setDescription('Titre de l\'embed')
|
||||
.setRequired(true))
|
||||
.addStringOption(option =>
|
||||
option.setName('description')
|
||||
.setDescription('Description de l\'embed')
|
||||
.setRequired(true))
|
||||
.addStringOption(option =>
|
||||
option.setName('color')
|
||||
.setDescription('Couleur de l\'embed (hex, ex: #FF0000)')
|
||||
.setRequired(false))
|
||||
.setDefaultMemberPermissions(PermissionFlagsBits.ManageMessages),
|
||||
async execute(interaction) {
|
||||
const title = interaction.options.getString('title');
|
||||
const description = interaction.options.getString('description');
|
||||
const colorInput = interaction.options.getString('color');
|
||||
|
||||
let color = 0x5865F2;
|
||||
if (colorInput) {
|
||||
const hexMatch = colorInput.match(/^#?([0-9A-Fa-f]{6})$/);
|
||||
if (hexMatch) {
|
||||
color = parseInt(hexMatch[1], 16);
|
||||
}
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle(title)
|
||||
.setDescription(description)
|
||||
.setColor(color)
|
||||
.setFooter({ text: `Créé par ${interaction.user.tag}`, iconURL: interaction.user.displayAvatarURL() })
|
||||
.setTimestamp();
|
||||
|
||||
await interaction.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
||||
@@ -1,4 +1,6 @@
|
||||
const {SlashCommandBuilder, EmbedBuilder} = require("discord.js");
|
||||
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
||||
const { formatUptime } = require('../../utils/helpers');
|
||||
const { colors } = require('../../utils/constants');
|
||||
|
||||
module.exports = {
|
||||
category: 'info',
|
||||
@@ -6,42 +8,55 @@ module.exports = {
|
||||
.setName('info')
|
||||
.setDescription('Obtenir les informations du bot'),
|
||||
async execute(interaction) {
|
||||
const uptime = formatUptime(process.uptime());
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setTitle('📝 Informations du Bot')
|
||||
.setColor('DarkVividPink')
|
||||
.addFields(
|
||||
{
|
||||
name:'👩💻 Développeuse Principale',
|
||||
value:'<@361526553940721684>',
|
||||
inline: true
|
||||
},
|
||||
|
||||
{
|
||||
name: '🧠 Langages et environnement',
|
||||
value: [
|
||||
'• **Langage :** <:javascript:1425179797692092506> JavaScript (ECMAScript 2024)',
|
||||
'• **Backend :** <:nodejs:1425179878252089435> Node.js v22.20.0',
|
||||
'• **Librairies :** <:discordjs:1425179852536938670> Discord.js v14.22',
|
||||
'• **IDE :** <:webstorm:1429190717066055841> JetBrains WebStorm 2025.2.3',
|
||||
].join('\n'),
|
||||
inline: false
|
||||
},
|
||||
{
|
||||
name: '💡 Date de création',
|
||||
value: '20 Août 2025'
|
||||
},
|
||||
{
|
||||
name: '⏱️ Uptime',
|
||||
value: `${Math.floor(process.uptime()/3600)}h ${Math.floor(process.uptime()%3600/60)}m`,
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({
|
||||
text: 'Fembot • Made with love by Syxpi 💞',
|
||||
.setAuthor({
|
||||
name: `Système d'Information • ${interaction.client.user.username}`,
|
||||
iconURL: interaction.client.user.displayAvatarURL()
|
||||
})
|
||||
.setColor(colors.info)
|
||||
.setThumbnail(interaction.client.user.displayAvatarURL({dynamic: true, size: 256}))
|
||||
.setDescription('Voici les détails techniques et statistiques concernant mon fonctionnement actuel.')
|
||||
.addFields(
|
||||
{
|
||||
name: '👑 Propriétaire',
|
||||
value: `> <@361526553940721684> (Lumi)`,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: '⌛ En ligne depuis',
|
||||
value: `> \`${uptime}\``,
|
||||
inline: true
|
||||
},
|
||||
{
|
||||
name: '🛠️ Stack Technique',
|
||||
value: [
|
||||
'```yml',
|
||||
'Langage: JavaScript (ES2024)',
|
||||
'Runtime: Node.js v25.2.1',
|
||||
'Library: Discord.js v14.22.1',
|
||||
'IDE: JetBrains WebStorm',
|
||||
'```'
|
||||
].join('\n'),
|
||||
inline: false
|
||||
},
|
||||
{
|
||||
name: '📈 Statistiques Globales',
|
||||
value: [
|
||||
`• **Guildes:** \`${interaction.client.guilds.cache.size}\``,
|
||||
`• **Membres:** \`${interaction.client.guilds.cache.reduce((acc, guild) => acc + guild.memberCount, 0)}\``,
|
||||
`• **Commandes:** \`${interaction.client.commands.size}\``,
|
||||
].join('\n'),
|
||||
inline: true
|
||||
}
|
||||
)
|
||||
.setFooter({
|
||||
text: `France Femboy Bot • Développé avec passion par Lumi 💞`,
|
||||
iconURL: interaction.client.user.displayAvatarURL()
|
||||
})
|
||||
.setTimestamp();
|
||||
|
||||
await interaction.reply({ embeds: [embed] });
|
||||
await interaction.reply({embeds: [embed]});
|
||||
},
|
||||
};
|
||||
};
|
||||
334
commands/info/profil.js
Normal file
334
commands/info/profil.js
Normal file
@@ -0,0 +1,334 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder, MessageFlags } = require('discord.js');
|
||||
const db = require('../../functions/database/db.js');
|
||||
const { getUserXP, getUserRank } = require('../../functions/xp/xp.js');
|
||||
const { colors } = require('../../utils/constants');
|
||||
|
||||
const BADGE_EMOJIS = {
|
||||
'staff': '👨💼',
|
||||
'partner': '<:discord_partener:1437046788916904097>',
|
||||
'hypesquad': '<:hypesquad_balance:1437046792922464337>',
|
||||
'hypesquad_bravery': '<:hypesquad_bravery:1437046793899872467>',
|
||||
'hypesquad_brilliance': '<:hypesquad_brilliance:1437046794868756550>',
|
||||
'hypesquad_balance': '<:hypesquad_balance:1437046792922464337>',
|
||||
'hypesquad_events': '<:hypesquad_events:1437046795778920448>',
|
||||
'early_supporter': '<:early_supporter:1437046790087250071>',
|
||||
'bug_hunter_level_1': '🐛',
|
||||
'bug_hunter_level_2': '🐛',
|
||||
'verified_developer': '✅',
|
||||
'active_developer': '<:active_developer:1437049369936531587>',
|
||||
'certified_moderator': '🛡️',
|
||||
'bot_http_interactions': '🤖',
|
||||
'quests': '<:quests:1437046809464934492>',
|
||||
'slash_commands': '<:slash_commands:1437046810458984553>',
|
||||
'orbs': '<:orbs:1437046808185540628>',
|
||||
'nitro': '<:nitro:1437046796810715136>',
|
||||
'nitro_1_month': '<:nitro_1_month:1437046798685442241>',
|
||||
'nitro_3_months': '<:nitro_3_months:1437046801550278757>',
|
||||
'nitro_6_months': '<:nitro_6_months:1437046805102723143>',
|
||||
'nitro_1_year': '<:nitro_1_year:1437046799515783198>',
|
||||
'nitro_2_years': '<:nitro_2_years:1437046800522416138>',
|
||||
'nitro_3_years': '<:nitro_3_years:1437046802519035924>',
|
||||
'nitro_5_years': '<:nitro_5_years:1437046803747967016>',
|
||||
'nitro_6_years': '<:nitro_6_years:1437046806747021514>',
|
||||
'boost': '<:boost:1437046778083016745>',
|
||||
'boost_2_months': '<:boost_2_months:1437046780322779266>',
|
||||
'boost_3_months': '<:boost_3_months:1437046781375414383>',
|
||||
'boost_6_months': '<:boost_6_months:1437046782247829616>',
|
||||
'boost_9_months': '<:boost_9_months:1437046783070044200>',
|
||||
'boost_12_months': '<:boost_12_months:1437046784445644930>',
|
||||
'boost_15_months': '<:boost_15_months:1437046785402081281>',
|
||||
'boost_18_months': '<:boost_18_months:1437046786643722342>',
|
||||
'boost_24_months': '<:boost_24_months:1437046787667136612>',
|
||||
};
|
||||
|
||||
function getDiscordBadges(user, member) {
|
||||
const badgeEmojis = [];
|
||||
|
||||
if (user.flags) {
|
||||
try {
|
||||
const flagsArray = user.flags.toArray();
|
||||
const flagToBadgeMap = {
|
||||
'Staff': 'staff', 'Partner': 'partner', 'HypeSquad': 'hypesquad',
|
||||
'HypeSquadOnlineHouse1': 'hypesquad_bravery', 'HypeSquadOnlineHouse2': 'hypesquad_brilliance', 'HypeSquadOnlineHouse3': 'hypesquad_balance',
|
||||
'HypeSquadEvents': 'hypesquad_events', 'BugHunterLevel1': 'bug_hunter_level_1', 'BugHunterLevel2': 'bug_hunter_level_2',
|
||||
'PremiumEarlySupporter': 'early_supporter', 'VerifiedDeveloper': 'verified_developer', 'ActiveDeveloper': 'active_developer',
|
||||
'CertifiedModerator': 'certified_moderator', 'BotHTTPInteractions': 'bot_http_interactions',
|
||||
'Quests': 'quests', 'QuestsEarly': 'quests', 'SlashCommands': 'slash_commands',
|
||||
};
|
||||
|
||||
for (const flag of flagsArray) {
|
||||
const flagLower = flag.toLowerCase();
|
||||
const badgeKey = flagToBadgeMap[flag];
|
||||
|
||||
if (badgeKey && BADGE_EMOJIS[badgeKey]) {
|
||||
badgeEmojis.push(BADGE_EMOJIS[badgeKey]);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (flagLower.includes('nitro')) {
|
||||
if (flagLower.match(/6.*year|year.*6|emerald/)) badgeEmojis.push(BADGE_EMOJIS.nitro_6_years);
|
||||
else if (flagLower.match(/5.*year|year.*5/)) badgeEmojis.push(BADGE_EMOJIS.nitro_5_years);
|
||||
else if (flagLower.match(/3.*year|year.*3/)) badgeEmojis.push(BADGE_EMOJIS.nitro_3_years);
|
||||
else if (flagLower.match(/2.*year|year.*2/)) badgeEmojis.push(BADGE_EMOJIS.nitro_2_years);
|
||||
else if (flagLower.match(/1.*year|year.*1/) && !flagLower.includes('month')) badgeEmojis.push(BADGE_EMOJIS.nitro_1_year);
|
||||
else if (flagLower.match(/6.*month|month.*6/)) badgeEmojis.push(BADGE_EMOJIS.nitro_6_months);
|
||||
else if (flagLower.match(/3.*month|month.*3/)) badgeEmojis.push(BADGE_EMOJIS.nitro_3_months);
|
||||
else if (flagLower.match(/1.*month|month.*1/)) badgeEmojis.push(BADGE_EMOJIS.nitro_1_month);
|
||||
else badgeEmojis.push(BADGE_EMOJIS.nitro);
|
||||
}
|
||||
else if (flagLower.includes('boost') && !flagLower.includes('server')) {
|
||||
if (flagLower.match(/24|two.*four|twenty.*four/i)) badgeEmojis.push(BADGE_EMOJIS.boost_24_months);
|
||||
else if (flagLower.match(/18|eighteen/i)) badgeEmojis.push(BADGE_EMOJIS.boost_18_months);
|
||||
else if (flagLower.match(/15|fifteen/i)) badgeEmojis.push(BADGE_EMOJIS.boost_15_months);
|
||||
else if (flagLower.match(/12|twelve|one.*year|1.*year/) && !flagLower.match(/18|15|24|128|112/i)) badgeEmojis.push(BADGE_EMOJIS.boost_12_months);
|
||||
else if (flagLower.match(/9|nine/) && !flagLower.match(/19|29|90|99/i)) badgeEmojis.push(BADGE_EMOJIS.boost_9_months);
|
||||
else if (flagLower.match(/6|six/) && !flagLower.match(/16|26|60|66|68|69/i)) badgeEmojis.push(BADGE_EMOJIS.boost_6_months);
|
||||
else if (flagLower.match(/3|three/) && !flagLower.match(/13|23|30|33|34|35|36|37|38|39/i)) badgeEmojis.push(BADGE_EMOJIS.boost_3_months);
|
||||
else if (flagLower.match(/2|two/) && !flagLower.match(/12|20|21|22|23|24|25|26|27|28|29/i)) badgeEmojis.push(BADGE_EMOJIS.boost_2_months);
|
||||
else badgeEmojis.push(BADGE_EMOJIS.boost);
|
||||
}
|
||||
else if (flagLower.includes('orb')) badgeEmojis.push(BADGE_EMOJIS.orbs);
|
||||
else if (flagLower.includes('quest')) badgeEmojis.push(BADGE_EMOJIS.quests);
|
||||
else if (flagLower.includes('slash')) badgeEmojis.push(BADGE_EMOJIS.slash_commands);
|
||||
}
|
||||
} catch (err) { console.warn('Erreur flags:', err.message); }
|
||||
}
|
||||
|
||||
const hasNitroBadge = badgeEmojis.some(e => typeof e === 'string' && e.includes('nitro'));
|
||||
const hasPremiumType = user.premiumType && user.premiumType !== 0;
|
||||
const hasBanner = user.banner;
|
||||
const hasAccentColor = user.accentColor;
|
||||
const hasAnimatedAvatar = user.avatar && user.avatar.startsWith('a_');
|
||||
const hasNitro = hasPremiumType || hasBanner || (hasAnimatedAvatar && hasAccentColor);
|
||||
|
||||
if (!hasNitroBadge && hasNitro) badgeEmojis.push(BADGE_EMOJIS.nitro);
|
||||
|
||||
if (member && member.premiumSince) {
|
||||
const hasBoostBadge = badgeEmojis.some(e => typeof e === 'string' && e.includes('boost'));
|
||||
if (!hasBoostBadge) {
|
||||
const boostDurationMs = Date.now() - member.premiumSince.getTime();
|
||||
const boostDurationMonths = Math.floor(boostDurationMs / (1000 * 60 * 60 * 24 * 30));
|
||||
|
||||
let boostBadge = BADGE_EMOJIS.boost;
|
||||
if (boostDurationMonths >= 24) boostBadge = BADGE_EMOJIS.boost_24_months;
|
||||
else if (boostDurationMonths >= 18) boostBadge = BADGE_EMOJIS.boost_18_months;
|
||||
else if (boostDurationMonths >= 15) boostBadge = BADGE_EMOJIS.boost_15_months;
|
||||
else if (boostDurationMonths >= 12) boostBadge = BADGE_EMOJIS.boost_12_months;
|
||||
else if (boostDurationMonths >= 9) boostBadge = BADGE_EMOJIS.boost_9_months;
|
||||
else if (boostDurationMonths >= 6) boostBadge = BADGE_EMOJIS.boost_6_months;
|
||||
else if (boostDurationMonths >= 3) boostBadge = BADGE_EMOJIS.boost_3_months;
|
||||
else if (boostDurationMonths >= 2) boostBadge = BADGE_EMOJIS.boost_2_months;
|
||||
|
||||
badgeEmojis.push(boostBadge);
|
||||
}
|
||||
}
|
||||
|
||||
return [...new Set(badgeEmojis)];
|
||||
}
|
||||
|
||||
function getStatusFrench(presence) {
|
||||
if (!presence || !presence.status) return { text: 'Hors ligne', emoji: '⚫' };
|
||||
switch (presence.status) {
|
||||
case 'online': return { text: 'En ligne', emoji: '🟢' };
|
||||
case 'idle': return { text: 'Absent', emoji: '🟡' };
|
||||
case 'dnd': return { text: 'Ne pas déranger', emoji: '🔴' };
|
||||
default: return { text: 'Hors ligne', emoji: '⚫' };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
category: 'info',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('profil')
|
||||
.setDescription('Afficher le profil d\'un utilisateur')
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand.setName('view').setDescription('Voir le profil d\'un utilisateur')
|
||||
.addUserOption(option => option.setName('user').setDescription('L\'utilisateur dont tu veux voir le profil').setRequired(false)))
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand.setName('set').setDescription('Modifier ton profil')
|
||||
.addStringOption(option => option.setName('signature').setDescription('Ta signature personnalisée (max 200 caractères)').setRequired(false).setMaxLength(200))
|
||||
.addStringOption(option => option.setName('birthday').setDescription('Ta date d\'anniversaire (JJ/MM/AAAA)').setRequired(false))
|
||||
.addStringOption(option => option.setName('color').setDescription('Couleur de ton profil (Hex: #RRGGBB)').setRequired(false))
|
||||
.addStringOption(option => option.setName('gender').setDescription('Ton genre/pronoms').setRequired(false).setMaxLength(50))
|
||||
.addStringOption(option => option.setName('location').setDescription('Ta localisation').setRequired(false).setMaxLength(100)))
|
||||
.addSubcommand(subcommand =>
|
||||
subcommand.setName('reset').setDescription('Réinitialiser ton profil')),
|
||||
async execute(interaction) {
|
||||
const subcommand = interaction.options.getSubcommand();
|
||||
|
||||
if (subcommand === 'view') {
|
||||
await interaction.deferReply();
|
||||
|
||||
const target = interaction.options.getUser('user') || interaction.user;
|
||||
const fetchedUser = await interaction.client.users.fetch(target.id, { force: true, cache: false }).catch(() => target);
|
||||
const member = await interaction.guild.members.fetch(target.id).catch(() => null);
|
||||
|
||||
if (!member) return interaction.editReply({ content: '❌ Cet utilisateur n\'est pas sur ce serveur.' });
|
||||
|
||||
try {
|
||||
const userXP = await getUserXP(target.id, interaction.guild.id);
|
||||
const [profiles] = await db.query('SELECT * FROM user_profiles WHERE userId = ? AND guildId = ?', [target.id, interaction.guild.id]);
|
||||
const profile = profiles[0] || null;
|
||||
|
||||
const badgeEmojis = getDiscordBadges(fetchedUser, member);
|
||||
const badgesText = badgeEmojis.length > 0 ? badgeEmojis.join(' ') : 'Aucun badge';
|
||||
const status = getStatusFrench(member.presence);
|
||||
|
||||
const accountAge = Math.floor((Date.now() - target.createdTimestamp) / (1000 * 60 * 60 * 24));
|
||||
const accountAgeYears = Math.floor(accountAge / 365);
|
||||
const accountAgeMonths = Math.floor((accountAge % 365) / 30);
|
||||
const accountAgeDays = accountAge % 30;
|
||||
|
||||
let accountAgeText = accountAgeYears > 0 ? `${accountAgeYears} an${accountAgeYears > 1 ? 's' : ''}` : '';
|
||||
if (accountAgeMonths > 0) accountAgeText += (accountAgeText ? ' ' : '') + `${accountAgeMonths} mois`;
|
||||
if (!accountAgeText) accountAgeText = `${accountAgeDays} jour${accountAgeDays > 1 ? 's' : ''}`;
|
||||
|
||||
const creationDate = `<t:${Math.floor(target.createdTimestamp / 1000)}:D>`;
|
||||
const voiceTimeMinutes = userXP?.totalVoiceTime || 0;
|
||||
const voiceTimeText = `${Math.floor(voiceTimeMinutes / 60)}h ${voiceTimeMinutes % 60}min`;
|
||||
|
||||
const rank = userXP ? await getUserRank(target.id, interaction.guild.id) : 0;
|
||||
|
||||
const [bumps] = await db.query('SELECT COUNT(*) as count FROM bumps WHERE userId = ? AND guildId = ?', [target.id, interaction.guild.id]);
|
||||
const [welcomeLogs] = await db.query('SELECT COUNT(*) as count FROM xp_logs WHERE userId = ? AND guildId = ? AND source = ?', [target.id, interaction.guild.id, 'welcome']);
|
||||
const [totalMessages] = await db.query('SELECT SUM(totalMessages) as total FROM user_xp WHERE userId = ?', [target.id]);
|
||||
|
||||
const embedColor = profile?.color && /^#[0-9A-F]{6}$/i.test(profile.color) ? profile.color : colors.primary;
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setAuthor({ name: `Profil de ${target.username}`, iconURL: target.displayAvatarURL({ dynamic: true }) })
|
||||
.setColor(embedColor)
|
||||
.setThumbnail(target.displayAvatarURL({ dynamic: true, size: 256 }))
|
||||
.setDescription(profile?.signature ? `\`\`\`${profile.signature}\`\`\`` : '*Aucune signature définie.*')
|
||||
.addFields(
|
||||
{ name: '👤 Informations', value: `• **Identifiant:** \`${target.id}\`\n• **Badges:** ${badgesText}\n• **Âge Compte:** \`${accountAgeText}\`\n• **Statut:** ${status.emoji} \`${status.text}\``, inline: false },
|
||||
{ name: '📊 Statistiques XP', value: `• **Niveau:** \`${userXP?.level || 0}\`\n• **XP Total:** \`${userXP?.xp || 0}\`\n• **Rang:** \`#${rank}\``, inline: true },
|
||||
{ name: '🎙️ Activité Vocal', value: `• **Temps:** \`${voiceTimeText}\`\n• **Bumps:** \`${bumps[0]?.count || 0}\`\n• **Messages:** \`${totalMessages[0]?.total || userXP?.totalMessages || 0}\``, inline: true },
|
||||
{ name: '🤝 Engagement', value: `• **Bienvenues:** \`${welcomeLogs[0]?.count || 0}\`\n• **Création:** ${creationDate}`, inline: false }
|
||||
)
|
||||
.setFooter({ text: `Demandé par ${interaction.user.tag}`, iconURL: interaction.user.displayAvatarURL() })
|
||||
.setTimestamp();
|
||||
|
||||
const personalInfos = [];
|
||||
if (profile?.gender) personalInfos.push(`• **Genre/Pronoms:** ${profile.gender}`);
|
||||
if (profile?.location) personalInfos.push(`• **Localisation:** ${profile.location}`);
|
||||
if (profile?.birthday) {
|
||||
const birthday = new Date(profile.birthday);
|
||||
const today = new Date();
|
||||
let age = today.getFullYear() - birthday.getFullYear();
|
||||
const monthDiff = today.getMonth() - birthday.getMonth();
|
||||
if (monthDiff < 0 || (monthDiff === 0 && today.getDate() < birthday.getDate())) age--;
|
||||
personalInfos.push(`• **Anniversaire:** ${birthday.toLocaleDateString('fr-FR')} (${age} ans)`);
|
||||
}
|
||||
|
||||
if (personalInfos.length > 0) {
|
||||
embed.addFields({ name: '📝 Infos Personnelles', value: personalInfos.join('\n'), inline: false });
|
||||
}
|
||||
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
|
||||
} catch (err) {
|
||||
console.error('Erreur profil:', err);
|
||||
await interaction.editReply({ content: '❌ Erreur lors de l\'affichage du profil.' });
|
||||
}
|
||||
|
||||
} else if (subcommand === 'set') {
|
||||
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||
|
||||
const signature = interaction.options.getString('signature');
|
||||
const birthdayInput = interaction.options.getString('birthday');
|
||||
const color = interaction.options.getString('color');
|
||||
const gender = interaction.options.getString('gender');
|
||||
const location = interaction.options.getString('location');
|
||||
|
||||
if (!signature && !birthdayInput && !color && !gender && !location) {
|
||||
return interaction.editReply({ content: '❌ Tu dois modifier au moins un élément.' });
|
||||
}
|
||||
|
||||
try {
|
||||
let birthdayDate = null;
|
||||
if (birthdayInput) {
|
||||
const parts = birthdayInput.split('/');
|
||||
if (parts.length === 3) {
|
||||
const day = parseInt(parts[0], 10);
|
||||
const month = parseInt(parts[1], 10) - 1;
|
||||
const year = parseInt(parts[2], 10);
|
||||
|
||||
const currentYear = new Date().getFullYear();
|
||||
if (year < 1900 || year > currentYear) {
|
||||
return interaction.editReply({ content: '❌ Année invalide. Doit être entre 1900 et aujourd\'hui.' });
|
||||
}
|
||||
|
||||
const date = new Date(year, month, day);
|
||||
if (date.getFullYear() === year && date.getMonth() === month && date.getDate() === day) {
|
||||
// Vérifier si la date est dans le futur
|
||||
if (date > new Date()) {
|
||||
return interaction.editReply({ content: '❌ Tu ne peux pas être né dans le futur !' });
|
||||
}
|
||||
birthdayDate = `${year}-${month + 1}-${day}`;
|
||||
} else {
|
||||
return interaction.editReply({ content: '❌ Date invalide. Format: JJ/MM/AAAA' });
|
||||
}
|
||||
} else {
|
||||
return interaction.editReply({ content: '❌ Format de date invalide. Utilise JJ/MM/AAAA' });
|
||||
}
|
||||
}
|
||||
|
||||
if (color && !/^#[0-9A-F]{6}$/i.test(color)) {
|
||||
return interaction.editReply({ content: '❌ Couleur invalide. Utilise le format Hex (ex: #FF0000).' });
|
||||
}
|
||||
|
||||
const [profiles] = await db.query('SELECT * FROM user_profiles WHERE userId = ? AND guildId = ?', [interaction.user.id, interaction.guild.id]);
|
||||
|
||||
if (profiles.length > 0) {
|
||||
const updates = [];
|
||||
const params = [];
|
||||
|
||||
if (signature) { updates.push('signature = ?'); params.push(signature); }
|
||||
if (birthdayDate) { updates.push('birthday = ?'); params.push(birthdayDate); }
|
||||
if (color) { updates.push('color = ?'); params.push(color); }
|
||||
if (gender) { updates.push('gender = ?'); params.push(gender); }
|
||||
if (location) { updates.push('location = ?'); params.push(location); }
|
||||
|
||||
updates.push('updatedAt = ?');
|
||||
params.push(Date.now());
|
||||
params.push(interaction.user.id);
|
||||
params.push(interaction.guild.id);
|
||||
|
||||
await db.query(`UPDATE user_profiles SET ${updates.join(', ')} WHERE userId = ? AND guildId = ?`, params);
|
||||
} else {
|
||||
await db.query(
|
||||
'INSERT INTO user_profiles (userId, guildId, signature, birthday, color, gender, location, updatedAt) VALUES (?, ?, ?, ?, ?, ?, ?, ?)',
|
||||
[
|
||||
interaction.user.id,
|
||||
interaction.guild.id,
|
||||
signature || null,
|
||||
birthdayDate || null,
|
||||
color || null,
|
||||
gender || null,
|
||||
location || null,
|
||||
Date.now()
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
const embed = new EmbedBuilder().setTitle('✅ Profil Modifié').setColor(colors.success).setDescription('Ton profil a été mis à jour avec succès !').setTimestamp();
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
} catch (err) {
|
||||
console.error('Erreur set profil:', err);
|
||||
await interaction.editReply({ content: '❌ Erreur lors de la modification du profil.' });
|
||||
}
|
||||
|
||||
} else if (subcommand === 'reset') {
|
||||
await interaction.deferReply({ flags: MessageFlags.Ephemeral });
|
||||
try {
|
||||
await db.query('DELETE FROM user_profiles WHERE userId = ? AND guildId = ?', [interaction.user.id, interaction.guild.id]);
|
||||
const embed = new EmbedBuilder().setTitle('✅ Profil Réinitialisé').setColor(colors.success).setDescription('Ton profil a été entièrement réinitialisé.').setTimestamp();
|
||||
await interaction.editReply({ embeds: [embed] });
|
||||
} catch (err) {
|
||||
console.error('Erreur reset profil:', err);
|
||||
await interaction.editReply({ content: '❌ Erreur lors de la réinitialisation du profil.' });
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
53
commands/info/serverinfo.js
Normal file
53
commands/info/serverinfo.js
Normal file
@@ -0,0 +1,53 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder, GuildVerificationLevel } = require('discord.js');
|
||||
const { colors, emojis } = require('../../utils/constants');
|
||||
|
||||
const verificationLevels = {
|
||||
[GuildVerificationLevel.None]: 'Aucune',
|
||||
[GuildVerificationLevel.Low]: 'Faible',
|
||||
[GuildVerificationLevel.Medium]: 'Moyenne',
|
||||
[GuildVerificationLevel.High]: 'Élevée',
|
||||
[GuildVerificationLevel.VeryHigh]: 'Très Élevée'
|
||||
};
|
||||
|
||||
module.exports = {
|
||||
category: 'info',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('serverinfo')
|
||||
.setDescription('Affiche les informations du serveur.'),
|
||||
async execute(interaction) {
|
||||
const guild = interaction.guild;
|
||||
const owner = await guild.fetchOwner();
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setAuthor({
|
||||
name: guild.name,
|
||||
iconURL: guild.iconURL({ dynamic: true }) || undefined
|
||||
})
|
||||
.setTitle(`${emojis.server} Informations du Serveur`)
|
||||
.setColor(colors.info)
|
||||
.setThumbnail(guild.iconURL({ dynamic: true, size: 256 }) || null)
|
||||
.addFields(
|
||||
{ name: '👑 Propriétaire', value: `${owner.user.toString()}\n\`${owner.user.tag}\``, inline: true },
|
||||
{ name: `${emojis.id} ID`, value: `\`${guild.id}\``, inline: true },
|
||||
{ name: `${emojis.calendar} Créé le`, value: `<t:${Math.floor(guild.createdTimestamp / 1000)}:F>`, inline: true },
|
||||
{ name: '👥 Membres', value: `\`${guild.memberCount.toLocaleString()}\``, inline: true },
|
||||
{ name: '💬 Canaux', value: `\`${guild.channels.cache.size}\``, inline: true },
|
||||
{ name: '😀 Emojis', value: `\`${guild.emojis.cache.size}\``, inline: true },
|
||||
{ name: '🎭 Rôles', value: `\`${guild.roles.cache.size}\``, inline: true },
|
||||
{ name: '✅ Vérification', value: `\`${verificationLevels[guild.verificationLevel] || 'Inconnue'}\``, inline: true },
|
||||
{ name: '🔒 Sécurité', value: guild.mfaLevel === 1 ? '`Élevé (2FA)`' : '`Normal`', inline: true }
|
||||
)
|
||||
.setFooter({ text: `${guild.name} • ${interaction.client.user.username}`, iconURL: interaction.client.user.displayAvatarURL() })
|
||||
.setTimestamp();
|
||||
|
||||
if (guild.description) {
|
||||
embed.setDescription(guild.description);
|
||||
}
|
||||
|
||||
if (guild.banner) {
|
||||
embed.setImage(guild.bannerURL({ dynamic: true, size: 1024 }));
|
||||
}
|
||||
|
||||
await interaction.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
||||
70
commands/info/userinfo.js
Normal file
70
commands/info/userinfo.js
Normal file
@@ -0,0 +1,70 @@
|
||||
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
|
||||
const { colors, emojis } = require('../../utils/constants');
|
||||
|
||||
function getStatusFrench(presence) {
|
||||
if (!presence || !presence.status) return { text: 'Hors ligne', emoji: '⚫' };
|
||||
switch (presence.status) {
|
||||
case 'online': return { text: 'En ligne', emoji: '🟢' };
|
||||
case 'idle': return { text: 'Absent', emoji: '🟡' };
|
||||
case 'dnd': return { text: 'Ne pas déranger', emoji: '🔴' };
|
||||
default: return { text: 'Hors ligne', emoji: '⚫' };
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
category: 'info',
|
||||
data: new SlashCommandBuilder()
|
||||
.setName('userinfo')
|
||||
.setDescription('Affiche les informations d\'un utilisateur.')
|
||||
.addUserOption(option =>
|
||||
option.setName('user')
|
||||
.setDescription('L\'utilisateur dont tu veux voir les informations')
|
||||
.setRequired(false)),
|
||||
async execute(interaction) {
|
||||
const target = interaction.options.getUser('user') || interaction.user;
|
||||
const member = await interaction.guild.members.fetch(target.id).catch(() => null);
|
||||
|
||||
const embed = new EmbedBuilder()
|
||||
.setAuthor({
|
||||
name: target.displayName,
|
||||
iconURL: target.displayAvatarURL({ dynamic: true })
|
||||
})
|
||||
.setTitle(`${emojis.user} Informations Utilisateur`)
|
||||
.setColor(colors.info)
|
||||
.setThumbnail(target.displayAvatarURL({ dynamic: true, size: 256 }))
|
||||
.addFields(
|
||||
{ name: `${emojis.id} ID`, value: `\`${target.id}\``, inline: true },
|
||||
{ name: `${emojis.calendar} Compte créé`, value: `<t:${Math.floor(target.createdTimestamp / 1000)}:F>`, inline: true },
|
||||
{ name: '🤖 Bot', value: target.bot ? '`Oui`' : '`Non`', inline: true }
|
||||
)
|
||||
.setFooter({ text: `${interaction.guild.name} • ${interaction.client.user.username}`, iconURL: interaction.client.user.displayAvatarURL() })
|
||||
.setTimestamp();
|
||||
|
||||
if (member) {
|
||||
const status = getStatusFrench(member.presence);
|
||||
const roles = member.roles.cache.filter(r => r.id !== interaction.guild.id);
|
||||
const rolesDisplay = roles.size > 0 ? roles.sort((a, b) => b.position - a.position).map(r => r.toString()).slice(0, 10).join(', ') : '`Aucun`';
|
||||
|
||||
embed.addFields(
|
||||
{ name: '📥 A rejoint le', value: `<t:${Math.floor(member.joinedTimestamp / 1000)}:F>`, inline: true },
|
||||
{ name: '⏰ Statut', value: `${status.emoji} \`${status.text}\``, inline: true },
|
||||
{ name: '👑 Rôle le plus élevé', value: member.roles.highest.toString(), inline: true },
|
||||
{ name: '🎭 Rôles', value: rolesDisplay, inline: false }
|
||||
);
|
||||
|
||||
if (member.nickname) {
|
||||
embed.addFields({ name: '📝 Surnom', value: `\`${member.nickname}\``, inline: true });
|
||||
}
|
||||
|
||||
if (roles.size > 10) {
|
||||
embed.addFields({ name: '📊 Total de rôles', value: `\`${roles.size}\``, inline: true });
|
||||
}
|
||||
}
|
||||
|
||||
if (target.banner) {
|
||||
embed.setImage(target.bannerURL({ dynamic: true, size: 1024 }));
|
||||
}
|
||||
|
||||
await interaction.reply({ embeds: [embed] });
|
||||
},
|
||||
};
|
||||
Reference in New Issue
Block a user