AeThex-Bot-Master/aethex-bot/events/guildSetup.js
sirpiglr c2a34f398e Add server mode configuration and dynamic status updates
Introduces a new server mode configuration system (Federation/Standalone) with associated command changes, dynamic status rotation for the bot, and adds new commands and features.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: aed2e46d-25bb-4b73-81a1-bb9e8437c261
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Event-Id: b08e6ba5-7498-4b9f-b1c9-7dc11b362ddd
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/aed2e46d-25bb-4b73-81a1-bb9e8437c261/R9PkDi8
Replit-Helium-Checkpoint-Created: true
2025-12-09 23:26:33 +00:00

183 lines
6.2 KiB
JavaScript

const { EmbedBuilder, ActionRowBuilder, ButtonBuilder, ButtonStyle, PermissionFlagsBits } = require('discord.js');
const { setServerMode, EMBED_COLORS } = require('../utils/modeHelper');
module.exports = {
name: 'guildCreate',
async execute(guild, client, supabase) {
if (!supabase) return;
const { data: existingConfig } = await supabase
.from('server_config')
.select('mode')
.eq('guild_id', guild.id)
.maybeSingle();
if (existingConfig?.mode) {
return;
}
let targetChannel = null;
if (guild.systemChannel && guild.systemChannel.permissionsFor(guild.members.me)?.has(PermissionFlagsBits.SendMessages)) {
targetChannel = guild.systemChannel;
}
if (!targetChannel) {
const channels = guild.channels.cache
.filter(c =>
c.type === 0 &&
c.permissionsFor(guild.members.me)?.has(PermissionFlagsBits.SendMessages)
)
.sort((a, b) => a.position - b.position);
targetChannel = channels.first();
}
if (!targetChannel) {
try {
const owner = await guild.fetchOwner();
await sendSetupDM(owner, guild, client, supabase);
} catch (e) {
console.log(`[Setup] Could not send setup prompt to ${guild.name}`);
}
return;
}
await sendSetupEmbed(targetChannel, guild, client, supabase);
}
};
async function sendSetupEmbed(channel, guild, client, supabase) {
const embed = new EmbedBuilder()
.setColor(EMBED_COLORS.federated)
.setTitle('⚔️ Welcome to Warden!')
.setDescription(
`Thanks for adding **Warden** to **${guild.name}**!\n\n` +
`Choose how you want to run Warden:`
)
.addFields(
{
name: '🌐 Join the Federation',
value:
'• Unified XP across all AeThex servers\n' +
'• Cross-server profiles and leaderboards\n' +
'• Realm selection and role sync\n' +
'• Part of the AeThex ecosystem',
inline: true
},
{
name: '🏠 Run Standalone',
value:
'• Isolated XP system for this server only\n' +
'• Local leaderboards and profiles\n' +
'• Full moderation and anti-nuke\n' +
'• Independent from other servers',
inline: true
}
)
.setFooter({ text: 'You can change this later with /config mode' })
.setTimestamp();
const row = new ActionRowBuilder()
.addComponents(
new ButtonBuilder()
.setCustomId('setup_federated')
.setLabel('Join Federation')
.setStyle(ButtonStyle.Primary)
.setEmoji('🌐'),
new ButtonBuilder()
.setCustomId('setup_standalone')
.setLabel('Run Standalone')
.setStyle(ButtonStyle.Secondary)
.setEmoji('🏠')
);
try {
const message = await channel.send({ embeds: [embed], components: [row] });
const collector = message.createMessageComponentCollector({
filter: (i) => {
return i.member.permissions.has(PermissionFlagsBits.Administrator) ||
i.member.id === guild.ownerId;
},
time: 86400000
});
collector.on('collect', async (interaction) => {
const mode = interaction.customId === 'setup_federated' ? 'federated' : 'standalone';
const success = await setServerMode(supabase, guild.id, mode);
if (success) {
const confirmEmbed = new EmbedBuilder()
.setColor(mode === 'federated' ? EMBED_COLORS.federated : EMBED_COLORS.standalone)
.setTitle(mode === 'federated' ? '🌐 Federation Mode Activated!' : '🏠 Standalone Mode Activated!')
.setDescription(
mode === 'federated'
? `**${guild.name}** is now part of the AeThex Federation!\n\n` +
'• XP earned here counts globally\n' +
'• Use `/verify` to link your AeThex account\n' +
'• Use `/set-realm` to choose your realm\n' +
'• Use `/help` to see all commands'
: `**${guild.name}** is now running in Standalone mode!\n\n` +
'• XP is tracked locally for this server\n' +
'• Use `/rank` to check your server level\n' +
'• Use `/leaderboard` to see top members\n' +
'• Use `/help` to see all commands'
)
.setFooter({ text: 'Change mode anytime with /config mode' })
.setTimestamp();
await interaction.update({ embeds: [confirmEmbed], components: [] });
collector.stop();
} else {
await interaction.reply({
content: 'Failed to set mode. Please try `/config mode` later.',
ephemeral: true
});
}
});
collector.on('end', async (collected, reason) => {
if (reason === 'time' && collected.size === 0) {
await setServerMode(supabase, guild.id, 'federated');
const timeoutEmbed = new EmbedBuilder()
.setColor(EMBED_COLORS.federated)
.setTitle('🌐 Federation Mode (Default)')
.setDescription(
`No selection was made, so **${guild.name}** has been set to Federation mode by default.\n\n` +
'Use `/config mode` to change this anytime.'
)
.setTimestamp();
await message.edit({ embeds: [timeoutEmbed], components: [] }).catch(() => {});
}
});
} catch (e) {
console.error('[Setup] Error sending setup embed:', e.message);
}
}
async function sendSetupDM(owner, guild, client, supabase) {
const embed = new EmbedBuilder()
.setColor(EMBED_COLORS.federated)
.setTitle('⚔️ Warden Setup Required')
.setDescription(
`Thanks for adding **Warden** to **${guild.name}**!\n\n` +
`I couldn't find a channel to send the setup prompt. Please use \`/config mode\` in your server to choose:\n\n` +
'**🌐 Federation** - Join the AeThex ecosystem with unified XP\n' +
'**🏠 Standalone** - Independent XP for your server only\n\n' +
'Until you choose, Federation mode is enabled by default.'
)
.setTimestamp();
try {
await owner.send({ embeds: [embed] });
await setServerMode(supabase, guild.id, 'federated');
} catch (e) {
await setServerMode(supabase, guild.id, 'federated');
}
}