tournament-helper-bot/utils.js

167 lines
7.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const https = require('node:https');
const fs = require('node:fs');
require('dotenv/config');
const { SlashCommandBuilder, MessageFlags, EmbedBuilder } = require('discord.js');
const { Tournament } = require("./data_objects/tournament.js");
const { tetrioRanks } = require("./data_objects/tetrio_ranks.js");
const xhr = {
get: (uri) => {
return new Promise((resolve, reject) => {
https.get(uri, (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
// Any 2xx status code signals a successful response but
// here we're only checking for 200.
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
res.resume();
return;
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
if (parsedData.success) {
resolve(parsedData);
} else {
reject(parsedData);
}
} catch (e) {
reject(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
})
});
},
};
async function reactionCheck(reaction, user, client, guild, teto, reg_role) {
async function deny(embedTitle, embedReason) {
reaction.users.remove(user.id);
const exampleEmbed = new EmbedBuilder()
.setColor(0xFF0000)
.setTitle(embedTitle)
.setDescription(embedReason)
.setTimestamp();
const channel = await client.channels.cache.get(reaction.message.channelId);
channel.send({ content: `<@${user.id}>`, embeds: [exampleEmbed] }).then(msg => {
setTimeout(() => msg.delete(), 10000)
});
}
try {
// Checking, if registration is open
const current_time = Date.now()/1000;
if(teto.unix_reg_end < current_time) {deny('Участники на данный турнир больше не принимаются', `Время на регистрацию истекло`); return}
// Checking, if user has linked his TETR.IO account
const search = await xhr.get(`https://ch.tetr.io/api/users/search/discord:${user.id}`);
if (!search.success) {
deny('Ваша регистрация отклонена', `По какой-то причине, бот не смог получить информацию о вашем профиле в TETR.IO`); return}
if (!search.data) {
deny('Ваша регистрация отклонена', `Вы не привязали этот Discord аккаунт к своему TETR.IO аккаунту.\n\n Чтобы это сделать, с главного меню TETR.IO перейдите в Config -> Account и проскролльте до самого конца`); return}
// Trying to get data about the user
const userData = await Promise.all([xhr.get(`https://ch.tetr.io/api/users/${search.data.user._id}`), xhr.get(`https://ch.tetr.io/api/users/${search.data.user._id}/summaries/league`)]);
if (!userData[0].success || !userData[1].success){ // If we failed to do this
deny('Ваша регистрация отклонена', `По какой-то причине, бот не смог получить информацию о вашем профиле в TETR.IO`); return}
// Checking, if user is not banned
if(userData[0].data.role === "banned"){
deny('Ваша регистрация отклонена', `Ваш аккаунт в TETR.IO забанен`); return}
// Check for rank restricted events if user even have rank
if((teto.rank_floor || teto.rank_roof) && (!userData[1].data.bestrank || userData[1].data.bestrank === "z")){
deny('Ваша регистрация отклонена', `Турнир имеет ограничения по рангу. У вас меньше 10 игр в Тетра Лиге и мы не можем понять, стоит ли вас пускать`); return}
// Checking, if user's rank is higher, than rank floor
if(teto.rank_floor && (tetrioRanks.indexOf(teto.rank_floor.toLowerCase()) > tetrioRanks.indexOf(userData[1].data.bestrank))){
deny('Ваша регистрация отклонена', `Ваш ранг слишком низкий для участия в данном турнире`); return}
// Checking, if user's rank is lower, than rank roof
if(teto.rank_roof && (tetrioRanks.indexOf(teto.rank_roof.toLowerCase()) < tetrioRanks.indexOf(userData[1].data.bestrank))){
deny('Ваша регистрация отклонена', `Ваш ранг слишком высокий для участия в данном турнире`); return}
// Checking, if user is from CIS
const cisCountries = ["RU", "BY", "AM", "AZ", "KZ", "KG", "MD", "TJ", "UZ", "TM", "UA"];
const { blacklist, whitelist } = require("./index.js");
if (!teto.international && (!cisCountries.includes(userData[0].data.country) || blacklist.has(user.id)) && !whitelist.has(user.id)){deny('Ваша регистрация отклонена', `${blacklist.includes(userData[0].data._id) ? "По данным, которые есть у нашей организации" : "Судя по вашему профилю в TETR.IO"}, вы не из СНГ`); return}
// Finally, if everything is ok - add him to participants list
teto.register(user.id, userData[0], userData[1]);
guild.members.addRole({ user: user, reason: "Захотел участвовать", role: reg_role });
console.log(`${user.tag} registred for a ${teto.title} event`);
} catch (error) {
const check_in_channel = await client.channels.fetch(process.env.BOT_LOGS_CHANNEL);
check_in_channel.send({ content: `Я поймал ошибку:\n\`${error}\`` });
return;
}
updateTournamentsJSON();
}
async function unreactionCheck(reaction, user, guild, teto, reg_role) {
guild.members.removeRole({ user: user, reason: "Расхотел участвовать", role: reg_role });
console.log(`${user.tag} unregistred for a ${teto.title} event`);
teto.removeParticipant(user.id);
updateTournamentsJSON();
}
function updateTournamentsJSON(){
const { tournaments } = require('./index.js');
fs.writeFile('./tournaments.json', JSON.stringify(Object.fromEntries(tournaments)), err => {
if (err) {
console.error(err);
} else {
console.log("tournaments.json was updated");
}
}
);
}
function updateWhitelistJSON(){
const { whitelist } = require('./index.js');
fs.writeFile('./whitelist.json', JSON.stringify([...whitelist]), err => {
if (err) {
console.error(err);
} else {
console.log("whitelist.json was updated");
}
}
);
}
function updateBlacklistJSON(){
const { blacklist } = require('./index.js');
fs.writeFile('./blacklist.json', JSON.stringify([...blacklist]), err => {
if (err) {
console.error(err);
} else {
console.log("blacklist.json was updated");
}
}
);
}
module.exports = {
xhr,
reactionCheck,
unreactionCheck,
updateTournamentsJSON,
updateWhitelistJSON,
updateBlacklistJSON
}