const GuildM = require('../models/guilds'); const roleRulesM = require('../models/autoRoleRule'); const feedsM = require('../models/feeds'); const leagueGameM = require('../models/leagueGame'); const leagueM = require('../models/league'); const xmlparser = require('xml-js') const {isValidObjectId} = require('mongoose') exports.getUser = (io)=> { return(req,res)=> { fetch('https://discord.com/api/users/@me', { headers: { authorization: req.headers.authorization, }, }) .then(result=>result.json()) .then(response => { res.json(response); }) } }; exports.guildData = (io,bot)=> { return async (req, res)=> { let userGuilds = await fetch('https://discord.com/api/users/@me/guilds', { headers: { authorization: req.headers.authorization, }, }) .then(result => result.json()) .then(response => { if(response.message) return response.message return response.filter(x=>x.owner==true); }) var promises = []; if(typeof userGuilds == 'string') return res.json({Error:userGuilds}) for(var guild of userGuilds) { promises.push(new Promise((resolve, reject) => { (async (guild)=> { var aux = await getSpecificGuildData(guild.id); var roleRules = aux ? await getRoleRules(guild.id):null; var guildTextChannels = aux ? aux.TextChannels:null; var emojis = aux ? aux.emojis:null; const dataObject = { id:guild.id, music:aux.guild?aux.guild.guild[0].music:false, strikes:aux.guild?aux.guild.guild[0].strikes:false, name:guild.name, icon:guild.icon?`https://cdn.discordapp.com/icons/${guild.id}/${guild.icon}.webp`:'https://cdn3.iconfinder.com/data/icons/popular-services-brands-vol-2/512/discord-512.png', features:guild.features, hasRem:aux.extra?true:false, memberCount:aux.extra?aux.extra.memberCount:null, roleRules, guildTextChannels, emojis }; resolve(dataObject); })(guild) })); } Promise.all(promises).then((values) => { return res.json(values); }); } async function getSpecificGuildData(guildID) { var extra = bot.guilds.cache.get(guildID) var guild = await GuildM.find({gID:guildID}) .then((guild,err)=> { if(err || guild.length==0) return; return {guild}; }); var TextChannels = []; var emojis = []; var roles = []; if(extra) { for(var channel of extra.channels.cache) { if(channel[1].type==0) { TextChannels.push( { 'id':channel[0], 'name':channel[1].name }); } } for(var emoji of extra.emojis.cache) { emojis.push( { 'id':emoji[0], 'name':emoji[1].name }); } for(var role of extra.roles.cache) { roles.push( { 'id':role[0], 'name':role[1].name }); } } console.log(roles) return {guild, extra, TextChannels, emojis, roles}; } async function getRoleRules(guildid) { return await roleRulesM.find({gID:guildid}).then((err, rules)=> { if(err || rules.length==0) return return rules }) } } exports.updateGuild = (io)=> { return (req, res)=> { GuildM.findOne({gID:req.body.guildID}) .then( (guild, err)=> { if(err || guild.length) return res.json({Error:'No guild'}); guild[`${req.body.property}`] =! guild[`${req.body.property}`]; GuildM.updateOne({gID:req.body.guildID}, guild).then(()=> { return res.json(guild); }) }) } } exports.getMessage = (bot)=> { return async (req, res)=> { if(!req.headers.guildid && !req.headers.messageid) return res.json({error:'No gid or messageid or both.'}) const TextChannels = bot.guilds.cache.get(req.headers.guildid).channels.cache.filter(x=>x.type==0); TextChannels.forEach(channel => { (async (channel)=> { var message try { message = await channel.messages.fetch(req.headers.messageid); } catch (error) { //message doesn't exist on this channel or at all } if(message) { message = message.content if(message.split('***').length %2 == 1) message = message.replaceAll('***', ''); if(message.split('**').length %2 == 1) message = message.replaceAll('**', ''); if(message.split('*').length %2 == 1) message = message.replaceAll('*', ''); if(message.split('~~').length %2 == 1) message = message.replaceAll('~~', ''); if(message.split('```').length %2 == 1) message = message.replaceAll('```', ''); if(message.split('``').length %2 == 1) message = message.replaceAll('``', ''); if(message.split('`').length %2 == 1) message = message.replaceAll('`', ''); res.json({message}) } })(channel) }); } } exports.getRules = async (req,res)=> { var payload; if(req.headers.guildid) { payload = await roleRulesM.find({gID:req.headers.guildid}) .then(rules =>{return rules}) .catch(()=>{return null}) return res.json(payload); } payload = await roleRulesM.findOne({_id:req.headers.id}) .then(rule=>{return rule}) .catch(()=>{return null}) return res.json(payload); } exports.deleteRule = async (req, res)=> { var deleted = await roleRulesM.findByIdAndDelete(req.headers.ruleid) .then(()=>{return {success:'Done'}}) .catch(()=>{return {error:'Failed to delete'}}); res.json(deleted); } exports.updateRule = (bot)=> { return async (req, res)=> { let args = req.headers; if(args.isnew == 'true') { const validationResult = await confirmArgs(args); if (validationResult.error) return res.json({error:validationResult.error}) var rule = new roleRulesM(); rule.gID = validationResult.gID; rule.mID = validationResult.mID; rule.roleID = validationResult.roleID; rule.roleEmoji = validationResult.roleEmoji; rule.roleName = validationResult.roleName; rule.save(err=> { if(err)res.json(err); res.json({success:true,rule}) }) } else { const validationResult = await confirmArgs(args); if (validationResult.error) return res.json({error:validationResult.error}) roleRulesM.findOne({id:args.id}).then(rule=> { if(!rule) return res.json({error:'DB Error'}); rule.gID = validationResult.gID; rule.mID = validationResult.mID; rule.roleID = validationResult.roleID; rule.roleEmoji = validationResult.roleEmoji; rule.roleName = validationResult.roleName; roleRulesM.updateOne({_id:rule.id}, rule,{upsert:true}).then(updatedG=> { res.json({success:true, rule}) }) }) } } async function confirmArgs(args) { var mID = args.messageid; var roleID = args.roleid; var roleEmoji = args.emojiid; var gID = args.gid; var roleName; if(!mID) return {error:'Message ID'} if(!roleID) return {error:'Role ID'} if(!roleEmoji) return {error:'Emoji ID'} if(!gID) return {error:'Guild ID'} var m = await (async ()=> { for(const [id, channel] of bot.channels.cache) { if(channel.type == 0) { try { const exists = await bot.channels.cache.get(id).messages.fetch(mID); if(exists) return m = true; } catch (error) {} } } })(); const r = bot.guilds.cache.get(gID).roles.cache.get(roleID); const e = bot.guilds.cache.get(gID).emojis.cache.get(roleEmoji); bot.guilds.cache.get(gID).emojis.cache.forEach(emoji=> { if(emoji.name == 'tuturu') console.log(emoji) }) console.log('Emoji', roleEmoji, e) if(!m || !r || !e) return m?(r?(e?false:{error:'Emoji ID'}):{error:'Role ID'}):{error:'Message ID'} roleName = r.name; return {mID, roleID, roleEmoji, roleName, gID} } } exports.getFeeds = async (req, res)=> { var payload = await feedsM.find({gID:req.headers.guildid}).then(res=>{return res}).catch(err=>{return err}); res.json(payload) } exports.getFeed = async (req, res)=> { var payload = await feedsM.find({_id:req.headers.feedid}).then(res=>{return res}).catch(err=>{return err}); res.json(payload) } exports.getChannelName = async (req,res)=> { var payload = await fetch('https://www.youtube.com/feeds/videos.xml?channel_id='+req.headers.channelid, { method: "GET", mode: "cors", }) .then(response=> { if(response.ok) return response.text(); }) .then(data=> { data = xmlparser.xml2json(data, { compact: true, space: 4 }); data = JSON.parse(data); return data.feed.author.name._text }) .catch(error=> { return error; }); res.json(payload); } exports.addFeed = (bot)=> { return async (req, res)=> { var headers= req.headers; var args = [headers.gid, headers.dcchannelid, headers.ytchannelid] const validationResult = await confirmArgs(args, bot); // console.log('Before new or old check', validationResult) if (validationResult.error) return res.json({error:validationResult.error}); if(!headers.feedid) { //new var feed = new feedsM(); feed.gID = headers.gid; feed.ChannelId = validationResult.channelId feed.YTChannelId = validationResult.YTChannelId; feed.CostumMessage = headers.costummessagei!=''?headers.costummessagei:'New video:'; feed.save(err=> { if(err)res.json({error:err}); res.json({success:true, feed}) }) } else { feedsM.findOne({id:args.id}).then(feed=> { if(!feed) return res.json({error:'DB Error'}); feed.gID = headers.gid; feed.ChannelId = validationResult.channelId feed.YTChannelId = validationResult.YTChannelId; feed.CostumMessage = headers.costummessagei!=''?headers.costummessagei:'New video:'; feedsM.updateOne({_id:feed.id}, feed,{upsert:true}).then(updatedG=> { res.json({success:true, feed}) }) }) } } } async function confirmArgs(args, bot) { var channelId = args[1]; var channelURL = args[2] async function getChannelId(url) { if(url.split('@').length<1) return return await fetch(url) .then(handleResponse) .then(handleData) .catch(handleError); function handleResponse(response) { if(response.ok) return response.text(); } function handleError(error) { return {error:'Bad youtube channel link.'}; } function handleData(data) { return data ? data.split('https://www.youtube.com/feeds/videos.xml?channel_id=')[1].split('"')[0] : false; } } const YTChannelId = await getChannelId(channelURL); if(YTChannelId.error) return {error:YTChannelId.error} const discordChannel = await bot.channels.fetch(channelId).then(channel=>{return channel }).catch(()=>{return null}); if(!discordChannel) return {error:'Provided discord channel id does not exist.'} var name = await fetch(`https://www.youtube.com/feeds/videos.xml?channel_id=${YTChannelId}`) .then(response => { return response.text() }) .then(data=> { data = xmlparser.xml2json(data, { compact: true, space: 4 }); data = JSON.parse(data); return data.feed.author.name._text }) .catch(error=>{return error;}); return {YTChannelId, channelId, name, channelName:discordChannel.name} } exports.deleteFeed = (req,res) => { feedsM.findOneAndDelete({_id:req.headers.feedid}).then(()=>{res.json({success:true})}).catch(error=>{res.json({error})}) } exports.getTournamentPage = (req,res)=> { if(!req.query.league) return res.render('leagues'); if(!isValidObjectId(req.query.league)) return res.redirect('/leagues') leagueM.findById(req.query.league) .then(league=> { if(league) res.render('leagues') }) .catch( res.render('leagues') ) } exports.getAllLeagues = (req, res)=> { leagueM.find() .then((leagues, err)=> { if(err) return res.json({Error:'Yea there was a problem.'}); if(!leagues) return res.json({Error:'Yea there was a problem.'}); if(leagues.length==0) return res.json({Error:'No leagues.'}) return res.json({data:leagues}) }) .catch(err=>console.log('Error finding leagues.')) } exports.getLeague = async (req, res)=> { if(!isValidObjectId(req.headers.leagueid)) return res.json({Error:'Yea this aint it chief... stop trying to mess with the system.'}) leagueM.findById(req.headers.leagueid) .then((league, err)=> { if(err) return res.json({Error:'Yea there was a problem.'}); if(!league) return res.json({Error:'Yea there was a problem.'}); if(league.length==0) return res.json({Error:'No leagues.'}) return res.json({data:league}) }) .catch(err=>console.log()) } exports.getLeaguePage = (req,res)=> { if(req.originalUrl == '/leagues/') return res.redirect('/leagues') return res.render('league') } exports.registerGame = async (req, res)=> { const GameData = { result:req.body.result, info:req.body.gameData, id: req.headers.id, leagueid: req.headers.leagueid } const data = req.body.data; var league = await leagueM.findById(GameData.leagueid).then(league=>{return league}) if(!league) return res.json({Error:'The league id is not valid'}) var Game = league.Games.filter(x=>(x.gId == GameData.id && x.Played == false)); if(Game.length == 0) return res.json({Error: 'The game id is not valid.'}) const gameStartTime = new Date(Date.now()-(GameData.info.gameTime*1000)).getTime(); //Epoch - gametime; const result = GameData.result; var update = await leagueGameM.findById(GameData.id).then(game=>{return game}); var PA = fillPlayer(update.PA, update.PA.Name == GameData.info.PlayerA.summonerName? GameData.info.PlayerA: GameData.info.PlayerB, update.PA.Name == GameData.result.winner); var PB = fillPlayer(update.PB, update.PB.Name == GameData.info.PlayerA.summonerName? GameData.info.PlayerA: GameData.info.PlayerB, update.PB.Name == GameData.result.winner); update.PA = PA; update.PB = PB; update.Winner = result.winner; update.WinCondition = result.winCondition; update.Played = true; update.PlayedTimeStamp = gameStartTime; const updated = await leagueGameM.findByIdAndUpdate(GameData.id,update).then(()=> { return true }) .catch(()=> { return false }) if(!updated) return res.json({Error:'The game failed to register.'}) var _PA = update.PA; _PA.extraData= update.PA.Name == GameData.info.PlayerA.summonerName? GameData.info.PlayerA: GameData.info.PlayerB; var _PB = update.PB; _PB.extraData = update.PA.Name == GameData.info.PlayerA.summonerName? GameData.info.PlayerA: GameData.info.PlayerB; Game[0] = { PA:_PA, PB:_PB, Winner:update.Winner, WinCondition:update.WinCondition, Played:true, PlayedTimeStamp:gameStartTime, gId:GameData.id } const index = league.Games.findIndex(x=>x.gId=GameData.id); league.Games[index] = Game[0]; const PAIndex = league.Players.findIndex(x=>x.Name == GameData.info.PlayerA.summonerName) const PBIndex = league.Players.findIndex(x=>x.Name == GameData.info.PlayerB.summonerName) const originalA = league.Players[PAIndex]; league.Players[PAIndex]={ Name: originalA.Name, Points: originalA.Points + (originalA.Name == result.winner?1:0), PlayedPoints: originalA.PlayedPoints + 1, Kills: originalA.Kills + GameData.info.PlayerA.Kills, Deaths: originalA.Deaths + GameData.info.PlayerA.Deaths, CreepScore: originalA.CreepScore + GameData.info.PlayerA.CS } const originalB = league.Players[PBIndex]; league.Players[PBIndex]={ Name: originalB.Name, Points: originalB.Points + (originalB.Name == result.winner?1:0), PlayedPoints: originalA.PlayedPoints + 1, Kills: originalB.Kills + GameData.info.PlayerB.Kills, Deaths: originalB.Deaths + GameData.info.PlayerB.Deaths, CreepScore: originalB.CreepScore + GameData.info.PlayerB.CS } const leagueUpdated = await leagueM.findByIdAndUpdate(GameData.leagueid,league).then(()=> { return true; }) .catch(()=>{return false}) if(!leagueUpdated) return res.json({Error:'Failed to update league.'}) res.json({success:true}) } function fillPlayer(P, data,winner) { P.winner = winner; P.Kills = data.Kills; P.Deaths = data.Deaths; P.CS = data.CS return P; } exports.getTournamentListenerPage = (req,res)=> { return res.render('leaguelistener') } exports.createLeague = async (req, res)=> { const verification = await verifyBody(req.body); if(verification.Error) return res.json(verification) var LeagueReference = { Name:verification.name, Players:[], Games:[], Owner:verification.owner } for(player of verification.players) { (async (player)=> { LeagueReference.Players.push( { Name:player, Points:0, PlayedPoints:0, Kills:0, Deaths:0, CreepScore:0 } ); })(player) } var games = await scheduler(verification.players) LeagueReference.Games=games; var league = new leagueM(); league.Name = LeagueReference.Name; league.Players = LeagueReference.Players; league.Games = LeagueReference.Games; league.Owner = LeagueReference.Owner league.save() .then(leagueS=> { return res.json({Success:true, data:leagueS}); }) .catch(err=> { return res.json({Error:'There was an error trying to save your league, try again later.'}); }) } async function verifyBody(body) { if(!body.owner) return {Error:'Stop trying to mess with the system.'}; if(!body.name) return {Error:'The league needs to be named.'}; if(!body.players) return {Error:'The league needs to have players playing it.'} var players = [...body.players.split(',')]; var playerPayload = []; var promises = []; for (var player of players) { (async (player)=> { promises.push(new Promise ((resolve)=> { fetch(`https://euw1.api.riotgames.com/lol/summoner/v4/summoners/by-name/${player}`, { method: "GET", headers: { "X-Riot-Token": "RGAPI-fc17a511-f587-495b-ac01-80716870d46b" } }) .then(response=>{return response.json()}) .then(res=> { if(res.status) playerPayload = {Error:'Player '+player+' does not exist.'}; try { playerPayload.push(res.name) } catch{} resolve(); }) .catch(err=>{console.log(err)}) })) })(player) } var payload = await Promise.all(promises).then(() => { if(playerPayload.Error) return playerPayload; return {name:body.name, owner:body.owner,players:playerPayload} }) return payload; } async function scheduler(players) { var games = []; var promises = []; for(var player of players) { (async (player)=> { promises.push(new Promise ((resolve)=> { for(var i = players.length-1; i>=0;i--) { (async (player2)=> { if(player == player2) resolve(); else { games.push({ PA:{ Name:player, winner:false, Kills:0, Deaths:0, CS:0 }, PB:{ Name:player2, winner:false, Kills:0, Deaths:0, CS:0 }, Winner:'', WinCondition:'', Played:false, PlayedTimeStamp:'', gId:'' }) resolve() } })(players[i]) } })) })(player) } var aux = []; for await(var game of games) { (async (game)=> { promises.push(new Promise ((resolve)=> { var gameM = new leagueGameM(); gameM.PA = game.PA; gameM.PB = game.PB; gameM.Winner = ' '; gameM.WinCondition = ' '; gameM.Played = false; gameM.PlayedTimeStamp = ' '; gameM.save().then((g)=> { game.gId = g.id; aux.push(game) resolve(); }) })); })(game); } var payload = await Promise.all(promises).then(() => { return aux; }) return payload; } exports.createLeaguePage = (req, res)=> { return res.render('createLeague'); } exports.createLeaguePage = (req, res)=> { res.render('createLeague'); } exports.getGame = (req, res)=> { return res.render('game') } exports.getGameData = (req, res)=> { //TODO: getGameData //TODO: send as json }