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
183 lines
6.2 KiB
JavaScript
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');
|
|
}
|
|
}
|