diff --git a/server-new/app/Controllers/Http/MatchesController.ts b/server-new/app/Controllers/Http/MatchesController.ts new file mode 100644 index 0000000..f6fa260 --- /dev/null +++ b/server-new/app/Controllers/Http/MatchesController.ts @@ -0,0 +1,4 @@ +// import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' + +export default class MatchesController { +} diff --git a/server-new/app/Controllers/Http/SummonersController.ts b/server-new/app/Controllers/Http/SummonersController.ts new file mode 100644 index 0000000..b07aa89 --- /dev/null +++ b/server-new/app/Controllers/Http/SummonersController.ts @@ -0,0 +1,79 @@ +import { HttpContextContract } from '@ioc:Adonis/Core/HttpContext' +import mongodb from '@ioc:Mongodb/Database' +import Jax from 'App/Services/Jax' +import SummonerService from 'App/Services/SummonerService' + +export default class SummonersController { + // private async getSeasons (puuid) { + // let seasons = await MatchRepository.seasons(puuid) + // return seasons.length ? seasons.map(s => s._id) : [10] + // } + + /** + * POST: get basic summoner data + */ + public async basic ({ request, response }: HttpContextContract) { + console.time('all') + const summoner = request.input('summoner') + const region = request.input('region') + console.log(summoner, region) + + const regexSummonerName = new RegExp('^[0-9\\p{L} _\\.]+$', 'u') + if (!regexSummonerName.exec(summoner)) { + return response.json(null) + } + + const finalJSON:any = {} + + try { + const account = await SummonerService.getAccount(summoner, region) + // Check if the summoner is found + if (!account) { + return response.json(null) + } + account.region = region + finalJSON.account = account + + // Summoner in DB + // const summonerDB = await Summoner.findOrCreate( + // { puuid: account.puuid }, + // { puuid: account.puuid } + // ) + + const summonersCollection = await mongodb.connection().collection('summoners') + const summonerDB = await summonersCollection.findOne({ puuid: account.puuid }) + if(!summonerDB) { + await summonersCollection.insertOne({ puuid: account.puuid }) + } + + // Summoner names + finalJSON.account.names = SummonerService.getAllSummonerNames(account, summonerDB) + + // MATCH LIST + await MatchService.updateMatchList(account, summonerDB) + finalJSON.matchList = summonerDB.matchList + + // All seasons the summoner has played + finalJSON.seasons = await this.getSeasons(account.puuid) + + // CURRENT GAME + const currentGame = await Jax.Spectator.summonerID(account.id, region) + finalJSON.playing = !!currentGame + finalJSON.current = currentGame + + // RANKED STATS + finalJSON.ranked = await SummonerService.getRanked(account, region) + + // SAVE IN DB + // await summonerDB.save() + await summonersCollection.updateOne({ puuid: account.puuid }, summonerDB) + } catch (error) { + console.log('username not found') + console.log(error) + return response.json(null) + } + + console.timeEnd('all') + return response.json(finalJSON) + } +} diff --git a/server-new/app/Services/SummonerService.ts b/server-new/app/Services/SummonerService.ts new file mode 100644 index 0000000..b432f60 --- /dev/null +++ b/server-new/app/Services/SummonerService.ts @@ -0,0 +1,79 @@ +'use strict' + +import Jax from './Jax' +import { SummonerDTO } from 'App/Services/Jax/src/Endpoints/SummonerEndpoint' +import { LeagueEntryDTO } from './Jax/src/Endpoints/LeagueEndpoint' + +class SummonerService { + private uniqueLeagues = ['CHALLENGER', 'GRANDMASTER', 'MASTER'] + private leaguesNumbers = { 'I': 1, 'II': 2, 'III': 3, 'IV': 4 } + + /** + * Helper to transform League Data from the Riot API + * @param league raw data of the league from Riot API + */ + private getleagueData (league?: LeagueEntryDTO) { + if (!league) { + return null + } + const fullRank = this.uniqueLeagues.includes(league.tier) ? league.tier : `${league.tier} ${league.rank}` + const winrate = +(league.wins * 100 / (league.wins + league.losses)).toFixed(1) + '%' + const shortName = this.uniqueLeagues.includes(league.tier) ? + league.leaguePoints : + league.tier[0] + this.leaguesNumbers[league.rank] + + return { + ...league, + fullRank, + winrate, + shortName, + } + } + + /** + * Get account infos for a searched summoner name + * @param summonerName + * @param region + */ + public async getAccount (summonerName: string, region: string) { + const name = summonerName.toLowerCase().replace(/ /g, '') + const account = await Jax.Summoner.summonerName(name, region) + return account + } + + /** + * Return the full list of old and actual summoner names + * @param account of the summoner + * @param summonerDB summoner in the database + */ + public getAllSummonerNames (account: SummonerDTO, summonerDB:any) { + const names = summonerDB.names ? summonerDB.names : [] + + if (!names.find((n: any) => n.name === account.name)) { + names.push({ + name: account.name, + date: new Date(), + }) + summonerDB.names = names + } + + return names + } + + /** + * Get ranked data for a specific Summoner + * @param account + * @param region + */ + public async getRanked (account: SummonerDTO, region: string) { + const ranked = await Jax.League.summonerID(account.id, region) + const result = { + soloQ: this.getleagueData(ranked.find(e => e.queueType === 'RANKED_SOLO_5x5')) || null, + flex5v5: this.getleagueData(ranked.find(e => e.queueType === 'RANKED_FLEX_SR')) || null, + flex3v3: this.getleagueData(ranked.find(e => e.queueType === 'RANKED_FLEX_TT')) || null, + } + return result + } +} + +export default new SummonerService() diff --git a/server-new/app/helpers.ts b/server-new/app/helpers.ts new file mode 100644 index 0000000..00cf0bf --- /dev/null +++ b/server-new/app/helpers.ts @@ -0,0 +1,50 @@ +/** + * League of Legends queues with defined role for each summoner + */ +const queuesWithRole = [ + 0, // Custom + 400, // Draft + 420, // Solo/Duo + 430, // Blind, + 440, // Flex + 700, // Clash +] + +/** +* League of Legends seasons timestamps +*/ +const seasons = { + 0: 9, + 1578628800000: 10, +} + +/** +* League of Legends all support item ids +*/ +const supportItems = [3850, 3851, 3853, 3854, 3855, 3857, 3858, 3859, 3860, 3862, 3863, 3864] + +module.exports = { + queuesWithRole, + seasons, + supportItems, + /** + * Get season number for a match + */ + getSeasonNumber (timestamp: number) { + const arrSeasons = Object.keys(seasons).map(k => Number(k)) + arrSeasons.push(timestamp) + arrSeasons.sort() + const indexSeason = arrSeasons.indexOf(timestamp) - 1 + return seasons[arrSeasons[indexSeason]] + }, + /** + * + * Sort array of Roles according to a specific order + * @param a first role + * @param b second role + */ + sortTeamByRole (a:any, b:any) { + const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'SUPPORT'] + return sortingArr.indexOf(a.role) - sortingArr.indexOf(b.role) + }, +} diff --git a/server-new/contracts/league.ts b/server-new/contracts/league.ts new file mode 100644 index 0000000..9b77485 --- /dev/null +++ b/server-new/contracts/league.ts @@ -0,0 +1,5 @@ +declare module '@ioc:Adonis/League' { + interface Account { + + } +} diff --git a/server-new/start/routes.ts b/server-new/start/routes.ts index df493eb..3364f8c 100644 --- a/server-new/start/routes.ts +++ b/server-new/start/routes.ts @@ -35,3 +35,13 @@ Route.get('jax', async () => { const summoner = await Jax.Summoner.summonerName('LeagueStats GG', 'euw1') return { player: summoner } }) + +Route.post('/summoner/basic', 'SummonersController.basic') +Route.post('/summoner/overview', 'SummonersController.overview') +Route.post('/summoner/champions', 'SummonersController.champions') +Route.post('/summoner/records', 'SummonersController.records') +Route.post('/summoner/live', 'SummonersController.liveMatchDetails') + +Route.post('/match', 'MatchesController.index') +Route.post('/match/details', 'MatchesController.show') +Route.post('/match/details/ranks', 'MatchesController.showRanks')