Add Sentinel anti-nuke listeners, federation role syncing, ticket system, and admin commands to the unified AeThex bot, consolidating functionality and enhancing security monitoring. Replit-Commit-Author: Agent Replit-Commit-Session-Id: e72fc1b7-94bd-4d6c-801f-cbac2fae245c Replit-Commit-Checkpoint-Type: intermediate_checkpoint Replit-Commit-Event-Id: 00c4494a-b436-4e48-b794-39cd745fb604 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3bdfff67-975a-46ad-9845-fbb6b4a4c4b5/e72fc1b7-94bd-4d6c-801f-cbac2fae245c/7DQc4BR Replit-Helium-Checkpoint-Created: true
157 lines
5.9 KiB
JavaScript
157 lines
5.9 KiB
JavaScript
const { SlashCommandBuilder, EmbedBuilder, PermissionFlagsBits } = require('discord.js');
|
|
|
|
module.exports = {
|
|
data: new SlashCommandBuilder()
|
|
.setName('admin')
|
|
.setDescription('Admin monitoring commands')
|
|
.setDefaultMemberPermissions(PermissionFlagsBits.Administrator)
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName('status')
|
|
.setDescription('View bot status and statistics')
|
|
)
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName('heat')
|
|
.setDescription('Check heat level of a user')
|
|
.addUserOption(option =>
|
|
option.setName('user')
|
|
.setDescription('User to check')
|
|
.setRequired(true)
|
|
)
|
|
)
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName('servers')
|
|
.setDescription('View all servers the bot is in')
|
|
)
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName('threats')
|
|
.setDescription('View current heat map (active threats)')
|
|
)
|
|
.addSubcommand(subcommand =>
|
|
subcommand
|
|
.setName('federation')
|
|
.setDescription('View federation role mappings')
|
|
),
|
|
|
|
async execute(interaction, supabase, client) {
|
|
const subcommand = interaction.options.getSubcommand();
|
|
|
|
if (subcommand === 'status') {
|
|
const guildCount = client.guilds.cache.size;
|
|
const memberCount = client.guilds.cache.reduce((sum, g) => sum + g.memberCount, 0);
|
|
const commandCount = client.commands.size;
|
|
const uptime = Math.floor(process.uptime());
|
|
const hours = Math.floor(uptime / 3600);
|
|
const minutes = Math.floor((uptime % 3600) / 60);
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0x7c3aed)
|
|
.setTitle('AeThex Bot Status')
|
|
.setThumbnail(client.user.displayAvatarURL())
|
|
.addFields(
|
|
{ name: 'Servers', value: `${guildCount}`, inline: true },
|
|
{ name: 'Total Members', value: `${memberCount.toLocaleString()}`, inline: true },
|
|
{ name: 'Commands', value: `${commandCount}`, inline: true },
|
|
{ name: 'Uptime', value: `${hours}h ${minutes}m`, inline: true },
|
|
{ name: 'Active Tickets', value: `${client.activeTickets.size}`, inline: true },
|
|
{ name: 'Heat Map Size', value: `${client.heatMap.size}`, inline: true }
|
|
)
|
|
.setTimestamp();
|
|
|
|
await interaction.reply({ embeds: [embed] });
|
|
}
|
|
|
|
if (subcommand === 'heat') {
|
|
const user = interaction.options.getUser('user');
|
|
const heat = client.getHeat(user.id);
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(heat >= client.HEAT_THRESHOLD ? 0xff0000 : heat > 0 ? 0xffaa00 : 0x00ff00)
|
|
.setTitle('User Heat Level')
|
|
.setThumbnail(user.displayAvatarURL())
|
|
.addFields(
|
|
{ name: 'User', value: user.tag, inline: true },
|
|
{ name: 'Heat Level', value: `${heat}/${client.HEAT_THRESHOLD}`, inline: true },
|
|
{ name: 'Status', value: heat >= client.HEAT_THRESHOLD ? 'DANGER' : heat > 0 ? 'Elevated' : 'Normal', inline: true }
|
|
)
|
|
.setTimestamp();
|
|
|
|
await interaction.reply({ embeds: [embed] });
|
|
}
|
|
|
|
if (subcommand === 'servers') {
|
|
const guilds = client.guilds.cache.map(g => `**${g.name}** - ${g.memberCount.toLocaleString()} members`).join('\n');
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0x7c3aed)
|
|
.setTitle('Connected Servers')
|
|
.setDescription(guilds || 'No servers')
|
|
.setFooter({ text: `Total: ${client.guilds.cache.size} servers` })
|
|
.setTimestamp();
|
|
|
|
await interaction.reply({ embeds: [embed], ephemeral: true });
|
|
}
|
|
|
|
if (subcommand === 'threats') {
|
|
const now = Date.now();
|
|
const activeThreats = [];
|
|
|
|
for (const [userId, events] of client.heatMap) {
|
|
const recentEvents = events.filter(e => now - e.timestamp < 10000);
|
|
if (recentEvents.length > 0) {
|
|
try {
|
|
const user = await client.users.fetch(userId).catch(() => null);
|
|
activeThreats.push({
|
|
user: user ? user.tag : userId,
|
|
heat: recentEvents.length,
|
|
actions: recentEvents.map(e => e.action).join(', ')
|
|
});
|
|
} catch (e) {
|
|
activeThreats.push({
|
|
user: userId,
|
|
heat: recentEvents.length,
|
|
actions: recentEvents.map(e => e.action).join(', ')
|
|
});
|
|
}
|
|
}
|
|
}
|
|
|
|
const description = activeThreats.length > 0
|
|
? activeThreats.map(t => `**${t.user}** - Heat: ${t.heat} (${t.actions})`).join('\n')
|
|
: 'No active threats detected.';
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(activeThreats.length > 0 ? 0xff0000 : 0x00ff00)
|
|
.setTitle('Active Threat Monitor')
|
|
.setDescription(description)
|
|
.setFooter({ text: `Heat threshold: ${client.HEAT_THRESHOLD}` })
|
|
.setTimestamp();
|
|
|
|
await interaction.reply({ embeds: [embed], ephemeral: true });
|
|
}
|
|
|
|
if (subcommand === 'federation') {
|
|
const mappings = [...client.federationMappings.entries()];
|
|
|
|
const description = mappings.length > 0
|
|
? mappings.map(([roleId, data]) => `<@&${roleId}> - Synced across realms`).join('\n')
|
|
: 'No federation role mappings configured.\nUse `/federation link` to set up cross-server roles.';
|
|
|
|
const embed = new EmbedBuilder()
|
|
.setColor(0x7c3aed)
|
|
.setTitle('Federation Role Mappings')
|
|
.setDescription(description)
|
|
.addFields(
|
|
{ name: 'Hub Guild', value: client.REALM_GUILDS.hub || 'Not set', inline: true },
|
|
{ name: 'Labs Guild', value: client.REALM_GUILDS.labs || 'Not set', inline: true },
|
|
{ name: 'GameForge Guild', value: client.REALM_GUILDS.gameforge || 'Not set', inline: true }
|
|
)
|
|
.setTimestamp();
|
|
|
|
await interaction.reply({ embeds: [embed], ephemeral: true });
|
|
}
|
|
},
|
|
};
|