2024-12-28 14:04:25 +00:00
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" ) ;
2025-01-09 17:28:12 +00:00
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 }
2024-12-28 14:04:25 +00:00
// 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
}