167 lines
7.5 KiB
JavaScript
167 lines
7.5 KiB
JavaScript
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
|
||
} |