diff --git a/commands/utility/avatar.js b/commands/utility/avatar.js new file mode 100644 index 0000000..b598cd3 --- /dev/null +++ b/commands/utility/avatar.js @@ -0,0 +1,25 @@ +const { SlashCommandBuilder, EmbedBuilder } = require('discord.js'); + +module.exports = { + data: new SlashCommandBuilder() + .setName('avatar') + .setDescription('Display a user\'s avatar in full size.') + .addUserOption((option) => + option + .setName('user') + .setDescription('The user to fetch the avatar for.') + ), + category: 'Utility', + async execute(interaction) { + const targetUser = interaction.options.getUser('user') ?? interaction.user; + const avatarUrl = targetUser.displayAvatarURL({ size: 1024, extension: 'png' }); + + const embed = new EmbedBuilder() + .setColor(0xa55eea) + .setTitle(`${targetUser.username}'s Avatar`) + .setImage(avatarUrl) + .setTimestamp(); + + await interaction.reply({ embeds: [embed] }); + }, +}; diff --git a/commands/utility/roll.js b/commands/utility/roll.js new file mode 100644 index 0000000..b894056 --- /dev/null +++ b/commands/utility/roll.js @@ -0,0 +1,54 @@ +const { SlashCommandBuilder, EmbedBuilder } = require('discord.js'); + +const clamp = (value, min, max) => Math.min(Math.max(value, min), max); + +const rollDice = (count, sides) => { + const rolls = []; + for (let i = 0; i < count; i += 1) { + rolls.push(1 + Math.floor(Math.random() * sides)); + } + return rolls; +}; + +module.exports = { + data: new SlashCommandBuilder() + .setName('roll') + .setDescription('Roll one or more dice with a custom number of sides.') + .addIntegerOption((option) => + option + .setName('sides') + .setDescription('Number of sides on each die (2-100).') + .setMinValue(2) + .setMaxValue(100) + ) + .addIntegerOption((option) => + option + .setName('count') + .setDescription('How many dice to roll (1-6).') + .setMinValue(1) + .setMaxValue(6) + ), + category: 'Utility', + async execute(interaction) { + const sidesInput = interaction.options.getInteger('sides') ?? 6; + const countInput = interaction.options.getInteger('count') ?? 1; + + const sides = clamp(sidesInput, 2, 100); + const count = clamp(countInput, 1, 6); + const rolls = rollDice(count, sides); + const total = rolls.reduce((sum, roll) => sum + roll, 0); + + const embed = new EmbedBuilder() + .setColor(0x20bf6b) + .setTitle('Dice Roll') + .addFields( + { name: 'Sides', value: `${sides}`, inline: true }, + { name: 'Dice', value: `${count}`, inline: true }, + { name: 'Total', value: `${total}`, inline: true }, + { name: 'Rolls', value: rolls.join(', ') } + ) + .setTimestamp(); + + await interaction.reply({ embeds: [embed] }); + }, +}; diff --git a/commands/utility/uptime.js b/commands/utility/uptime.js new file mode 100644 index 0000000..e71c704 --- /dev/null +++ b/commands/utility/uptime.js @@ -0,0 +1,34 @@ +const { SlashCommandBuilder, EmbedBuilder } = require('discord.js'); + +const formatDuration = (totalSeconds) => { + const seconds = Math.floor(totalSeconds % 60); + const minutes = Math.floor((totalSeconds / 60) % 60); + const hours = Math.floor((totalSeconds / 3600) % 24); + const days = Math.floor(totalSeconds / 86400); + + const parts = [ + days ? `${days}d` : null, + hours ? `${hours}h` : null, + minutes ? `${minutes}m` : null, + `${seconds}s`, + ].filter(Boolean); + + return parts.join(' '); +}; + +module.exports = { + data: new SlashCommandBuilder() + .setName('uptime') + .setDescription('Display how long the bot has been running.'), + category: 'Utility', + async execute(interaction) { + const uptimeSeconds = process.uptime(); + const embed = new EmbedBuilder() + .setColor(0x45aaf2) + .setTitle('Bot Uptime') + .setDescription(`Online for **${formatDuration(uptimeSeconds)}**.`) + .setTimestamp(); + + await interaction.reply({ embeds: [embed], ephemeral: true }); + }, +};