const { SlashCommandBuilder, EmbedBuilder, ChannelType } = require('discord.js'); module.exports = { data: new SlashCommandBuilder() .setName('serverinfo') .setDescription('View detailed information about this server'), async execute(interaction, supabase, client) { await interaction.deferReply(); const guild = interaction.guild; await guild.members.fetch().catch(() => {}); const textChannels = guild.channels.cache.filter(c => c.type === ChannelType.GuildText).size; const voiceChannels = guild.channels.cache.filter(c => c.type === ChannelType.GuildVoice).size; const categories = guild.channels.cache.filter(c => c.type === ChannelType.GuildCategory).size; const stageChannels = guild.channels.cache.filter(c => c.type === ChannelType.GuildStageVoice).size; const forumChannels = guild.channels.cache.filter(c => c.type === ChannelType.GuildForum).size; const roles = guild.roles.cache.size - 1; const emojis = guild.emojis.cache.size; const stickers = guild.stickers.cache.size; const boostLevel = guild.premiumTier; const boostCount = guild.premiumSubscriptionCount || 0; const boostEmojis = ['', '🌙', '🌟', '✨']; const totalMembers = guild.memberCount; const onlineMembers = guild.members.cache.filter(m => m.presence?.status !== 'offline').size; const botMembers = guild.members.cache.filter(m => m.user.bot).size; const humanMembers = totalMembers - botMembers; const owner = await guild.fetchOwner().catch(() => null); const verificationLevels = { 0: 'None', 1: 'Low', 2: 'Medium', 3: 'High', 4: 'Highest' }; const features = guild.features.slice(0, 5).map(f => f.split('_').map(w => w.charAt(0) + w.slice(1).toLowerCase()).join(' ') ); const embed = new EmbedBuilder() .setColor(0x7c3aed) .setAuthor({ name: guild.name, iconURL: guild.iconURL({ size: 64 }) }) .setThumbnail(guild.iconURL({ size: 256, dynamic: true })) .setDescription(guild.description || '*No server description*') .addFields( { name: '📋 General', value: [ `**ID:** \`${guild.id}\``, `**Owner:** ${owner ? owner.user.tag : 'Unknown'}`, `**Created:** ` ].join('\n'), inline: false }, { name: '👥 Members', value: [ `**Total:** ${totalMembers.toLocaleString()}`, `**Humans:** ${humanMembers.toLocaleString()}`, `**Bots:** ${botMembers.toLocaleString()}` ].join('\n'), inline: true }, { name: '💬 Channels', value: [ `**Text:** ${textChannels}`, `**Voice:** ${voiceChannels}`, `**Categories:** ${categories}`, forumChannels > 0 ? `**Forums:** ${forumChannels}` : null, stageChannels > 0 ? `**Stages:** ${stageChannels}` : null ].filter(Boolean).join('\n'), inline: true }, { name: '🎨 Assets', value: [ `**Roles:** ${roles}`, `**Emojis:** ${emojis}`, `**Stickers:** ${stickers}` ].join('\n'), inline: true }, { name: `${boostEmojis[boostLevel] || '💎'} Boost Status`, value: [ `**Level:** ${boostLevel}/3`, `**Boosts:** ${boostCount}`, `**Progress:** ${getBoostProgress(boostLevel, boostCount)}` ].join('\n'), inline: true }, { name: '🔒 Security', value: [ `**Verification:** ${verificationLevels[guild.verificationLevel] || 'Unknown'}`, `**2FA Required:** ${guild.mfaLevel === 1 ? 'Yes' : 'No'}`, `**NSFW Level:** ${getNsfwLevel(guild.nsfwLevel)}` ].join('\n'), inline: true } ) .setFooter({ text: `Requested by ${interaction.user.tag}`, iconURL: interaction.user.displayAvatarURL({ size: 32 }) }) .setTimestamp(); if (features.length > 0) { embed.addFields({ name: '✨ Features', value: features.map(f => `\`${f}\``).join(' • '), inline: false }); } if (guild.bannerURL()) { embed.setImage(guild.bannerURL({ size: 512 })); } if (guild.splash) { embed.addFields({ name: '🖼️ Splash', value: `[View Invite Splash](${guild.splashURL({ size: 512 })})`, inline: true }); } await interaction.editReply({ embeds: [embed] }); }, }; function getBoostProgress(level, count) { const thresholds = [2, 7, 14]; if (level >= 3) return '✅ Max Level'; const needed = thresholds[level]; const progress = Math.min(100, Math.floor((count / needed) * 100)); return `${count}/${needed} (${progress}%)`; } function getNsfwLevel(level) { const levels = { 0: 'Default', 1: 'Explicit', 2: 'Safe', 3: 'Age-Restricted' }; return levels[level] || 'Unknown'; }