const { SlashCommandBuilder, MessageFlags, EmbedBuilder } = require('discord.js'); const { Tournament } = require("../../data_objects/tournament.js"); const { tetrioRanks } = require("../../data_objects/tetrio_ranks.js"); const { xhr, reactionCheck, unreactionCheck, updateTournamentsJSON } = require("../../utils.js"); const { tournaments, blacklist, whitelist, trackedTournaments } = require("../../index.js"); module.exports = { data: new SlashCommandBuilder() .setName('create_event') .setDescription('Создать событие, доступное для регистрации') .addStringOption(option => option.setName('title') .setDescription('Название события') .setRequired(true)) .addIntegerOption(option => option.setName('unix_registration_end') .setDescription('Время завершения регистрации в формате UNIX времени') .setRequired(true)) .addIntegerOption(option => option.setName('unix_checkin_start') .setDescription('Время старта checkin в формате UNIX времени') .setRequired(true)) .addIntegerOption(option => option.setName('unix_checkin_end') .setDescription('Время завершения checkin в формате UNIX времени') .setRequired(true)) .addIntegerOption(option => option.setName('unix_tournament_start') .setDescription('Время планируемого старта турнира в формате UNIX времени') .setRequired(true)) .addStringOption(option => option.setName('description') .setDescription('Описание события')) .addStringOption(option => option.setName('prize_pool') .setDescription('Призовой фонд турнира')) .addStringOption(option => option.setName('rank_floor') .setDescription('Минимальный ранг для участия')) .addStringOption(option => option.setName('rank_roof') .setDescription('Максимальный ранг для участия')) .addBooleanOption(option => option.setName('international') .setDescription('Данный турнир международный')), async execute(interaction) { await interaction.deferReply({ flags: MessageFlags.Ephemeral }); const teto = new Tournament( interaction.options.getString('title'), interaction.options.getInteger('unix_registration_end'), interaction.options.getInteger('unix_checkin_start'), interaction.options.getInteger('unix_checkin_end'), interaction.options.getInteger('unix_tournament_start'), interaction.options.getString('rank_floor')??null, interaction.options.getString('rank_roof')??null, interaction.options.getBoolean('international')??null, interaction.options.getString('description')??null, interaction.options.getString('prize_pool')??null, ); // Checking, if Tournament information is valid const current_time = Date.now()/1000; if (teto.unix_reg_end < current_time) { const exampleEmbed = new EmbedBuilder() .setColor(0xFF0000) .setTitle('Некорректная информация о турнире') .setDescription('Время завершения регистрации уже наступило') .setTimestamp() interaction.followUp({ embeds: [exampleEmbed], flags: MessageFlags.Ephemeral }).then(msg => { setTimeout(() => msg.delete(), 10000) }); return } if (teto.unix_checkin_end < current_time) { const exampleEmbed = new EmbedBuilder() .setColor(0xFF0000) .setTitle('Некорректная информация о турнире') .setDescription('Время завершения checkin уже наступило') .setTimestamp() interaction.followUp({ embeds: [exampleEmbed], flags: MessageFlags.Ephemeral }).then(msg => { setTimeout(() => msg.delete(), 10000) }); return } if (teto.unix_tournament_start < current_time) { const exampleEmbed = new EmbedBuilder() .setColor(0xFF0000) .setTitle('Некорректная информация о турнире') .setDescription('Время старта турнира уже наступило') .setTimestamp() interaction.followUp({ embeds: [exampleEmbed], flags: MessageFlags.Ephemeral }).then(msg => { setTimeout(() => msg.delete(), 10000) }); return } if (teto.rank_floor !== null && !tetrioRanks.includes(teto.rank_floor.toLowerCase())) { const exampleEmbed = new EmbedBuilder() .setColor(0xFF0000) .setTitle('Некорректная информация о турнире') .setDescription(`Нет такого ранга ${teto.rank_floor}`) .setTimestamp() interaction.followUp({ embeds: [exampleEmbed], flags: MessageFlags.Ephemeral }).then(msg => { setTimeout(() => msg.delete(), 10000) }); return } if (teto.rank_roof !== null && !tetrioRanks.includes(teto.rank_roof.toLowerCase())) { const exampleEmbed = new EmbedBuilder() .setColor(0xFF0000) .setTitle('Некорректная информация о турнире') .setDescription(`Нет такого ранга ${teto.rank_roof}`) .setTimestamp() interaction.followUp({ embeds: [exampleEmbed], flags: MessageFlags.Ephemeral }).then(msg => { setTimeout(() => msg.delete(), 10000) }); return } const reg_role = await interaction.guild.roles.create( { name: `Регистрант на ${teto.title}`, reason: 'Роль необходима для отслеживания регистрантов турнира', permissions: 0n } ); const check_in_role = await interaction.guild.roles.create( { name: `Участник ${teto.title}`, reason: 'Роль необходима для отслеживания участников турнира', permissions: 0n } ); teto.setRoles(reg_role.id, check_in_role.id); tournaments.set(current_time.toString(), teto); const tournamentEmbed = new EmbedBuilder() .setColor(0x00FF00) .setTitle(teto.title) .setDescription(`${teto.description ? `${teto.description}\n` : ""}${teto.international ? "Международный" : "Только для игроков из стран СНГ"}${teto.prize_pool ? `\n**Призовой фонд: ${teto.prize_pool}**` : ""}${teto.rank_floor ? `\nМинимальный ранг для участия: ${teto.rank_floor}` : ""}${teto.rank_roof ? `\nМаксимальный ранг для участия: ${teto.rank_roof}` : ""}`) .setFooter({ text: 'Поставьте ✅, чтобы зарегистрироваться' }) .addFields( { name: "Завершение регистрации", value: `\n()`}, { name: "Check in", value: `\n()`}, { name: "Завершение check in", value: `\n()`}, { name: "**Старт турнира**", value: `\n()`}, ); // Send a message into the channel where command was triggered from const message = await interaction.followUp({ embeds: [tournamentEmbed], fetchReply: true }); message.react('✅'); updateTournamentsJSON(); trackedTournaments.push(current_time.toString()); teto.setMessageID(message.id, message.channel.id); const collectorFilter = (reaction, user) => { return reaction.emoji.name === '✅' && user.id !== message.author.id; }; // We gonna make sure, that user is eligible for a participation // NOTE: only 24,855127314815 days max const collector = message.createReactionCollector({ filter: collectorFilter, time: teto.unix_reg_end*1000 - current_time*1000, dispose: true }); collector.on('collect', async (reaction, user) => reactionCheck(reaction, user, interaction.client, interaction.guild, teto, reg_role)); collector.on('remove', async (reaction, user) => unreactionCheck(reaction, user, interaction.guild, teto, reg_role)); }, };