import { SlashCommandBuilder, ChatInputCommandInteraction, PermissionFlagsBits, EmbedBuilder, Colors, ChannelType } from 'discord.js'; import { prisma } from '../database'; import { t, SupportedLocale } from '../i18n'; import { MINI_GAMES, getAllMiniGames } from '../services/MiniGameRegistry'; export default { data: new SlashCommandBuilder() .setName('minigame') .setDescription('Manage mini-games for the server.') .setDescriptionLocalizations({ ko: '서버의 미니게임을 관리합니다.', }) .setDefaultMemberPermissions(PermissionFlagsBits.Administrator) // --- Toggle Subcommand --- .addSubcommand(subcommand => subcommand .setName('toggle') .setDescription('Enable or disable a specific mini-game.') .addStringOption(option => option.setName('game') .setDescription('Mini-game to toggle') .setRequired(true) .addChoices(...Object.values(MINI_GAMES).map(g => ({ name: g.name, value: g.key }))) ) .addBooleanOption(option => option.setName('enable') .setDescription('Whether to enable the mini-game') .setRequired(true) ) ) // --- Status Subcommand --- .addSubcommand(subcommand => subcommand .setName('status') .setDescription('View the current status of all mini-games.') ) // --- Channel Subcommand --- .addSubcommand(subcommand => subcommand .setName('channel') .setDescription('Set a dedicated channel for a mini-game.') .addStringOption(option => option.setName('game') .setDescription('Mini-game to set channel for') .setRequired(true) .addChoices(...Object.values(MINI_GAMES).map(g => ({ name: g.name, value: g.key }))) ) .addChannelOption(option => option.setName('channel') .setDescription('The channel to use (empty to allow all)') .addChannelTypes(ChannelType.GuildText) ) ), async execute(interaction: ChatInputCommandInteraction, locale: SupportedLocale) { if (!interaction.guildId) return; const subcommand = interaction.options.getSubcommand(); if (subcommand === 'toggle') { const gameKey = interaction.options.getString('game', true); const enable = interaction.options.getBoolean('enable', true); await prisma.miniGameConfig.upsert({ where: { guildId_gameKey: { guildId: interaction.guildId, gameKey } }, update: { enabled: enable }, create: { guildId: interaction.guildId, gameKey, enabled: enable }, }); const game = MINI_GAMES[gameKey]; const state = enable ? '활성화' : '비활성화'; const embed = new EmbedBuilder() .setColor(enable ? Colors.Green : Colors.Grey) .setTitle('🎮 미니게임 설정 변경') .setDescription(`${game.name} 미니게임이 **${state}**되었습니다.`); return interaction.reply({ embeds: [embed], ephemeral: true }); } if (subcommand === 'status') { const configs = await prisma.miniGameConfig.findMany({ where: { guildId: interaction.guildId }, }); const embed = new EmbedBuilder() .setColor(Colors.Blue) .setTitle('🎮 미니게임 현황') .setDescription('현재 서버의 미니게임 활성화 상태입니다.'); getAllMiniGames().forEach(game => { const config = configs.find(c => c.gameKey === game.key); const isEnabled = config?.enabled ?? false; const channel = config?.channelId ? `<#${config.channelId}>` : '모든 채널'; embed.addFields({ name: game.name, value: `상태: ${isEnabled ? '✅ 활성' : '❌ 비활성'}\n채널: ${channel}`, inline: true, }); }); return interaction.reply({ embeds: [embed], ephemeral: true }); } if (subcommand === 'channel') { const gameKey = interaction.options.getString('game', true); const channel = interaction.options.getChannel('channel'); await prisma.miniGameConfig.upsert({ where: { guildId_gameKey: { guildId: interaction.guildId, gameKey } }, update: { channelId: channel?.id || null }, create: { guildId: interaction.guildId, gameKey, channelId: channel?.id || null }, }); const game = MINI_GAMES[gameKey]; const channelMsg = channel ? `<#${channel.id}>` : '모든 채널'; const embed = new EmbedBuilder() .setColor(Colors.Gold) .setTitle('🎮 미니게임 채널 설정') .setDescription(`${game.name} 미니게임 전용 채널이 **${channelMsg}**로 설정되었습니다.`); return interaction.reply({ embeds: [embed], ephemeral: true }); } }, };