2019-10-05 18:01:01 +00:00
|
|
|
'use strict'
|
|
|
|
|
|
|
|
|
|
const Logger = use('Logger')
|
2019-10-01 19:39:26 +00:00
|
|
|
const Jax = use('Jax')
|
2019-11-03 17:49:58 +00:00
|
|
|
const BasicMatchTransformer = use('App/Transformers/BasicMatchTransformer')
|
2019-10-01 19:39:26 +00:00
|
|
|
|
|
|
|
|
class MatchHelper {
|
|
|
|
|
/**
|
2019-10-04 20:29:43 +00:00
|
|
|
* Add 100 matches at a time to MatchList until the stopFetching condition is true
|
|
|
|
|
* @param account of the summoner
|
|
|
|
|
* @param stopFetching condition to stop fetching the MatchList
|
2019-10-01 19:39:26 +00:00
|
|
|
*/
|
2019-10-04 20:29:43 +00:00
|
|
|
async fetchMatchListUntil(account, stopFetching) {
|
|
|
|
|
let matchList = []
|
|
|
|
|
let alreadyIn = false
|
|
|
|
|
let index = 0
|
|
|
|
|
do {
|
|
|
|
|
let newMatchList = (await Jax.Matchlist.accountID(account.accountId, index)).matches
|
|
|
|
|
matchList = [...matchList, ...newMatchList]
|
2019-11-12 20:03:02 +00:00
|
|
|
alreadyIn = newMatchList.length === 0 || stopFetching(newMatchList)
|
2019-10-10 18:56:48 +00:00
|
|
|
// If the match is made in another region : we stop fetching
|
|
|
|
|
if (matchList[matchList.length - 1].platformId.toLowerCase() !== account.region) {
|
|
|
|
|
alreadyIn = true;
|
|
|
|
|
}
|
2019-10-04 20:29:43 +00:00
|
|
|
index += 100
|
|
|
|
|
} while (!alreadyIn);
|
2019-10-01 19:39:26 +00:00
|
|
|
|
2019-11-12 20:03:02 +00:00
|
|
|
// Remove matches from MatchList made in another region and tutorial games
|
|
|
|
|
const tutorialModes = [2000, 2010, 2020]
|
|
|
|
|
matchList = matchList
|
|
|
|
|
.filter(m => {
|
|
|
|
|
const sameRegion = m.platformId.toLowerCase() === account.region
|
|
|
|
|
const notATutorialGame = !tutorialModes.includes(m.queue)
|
|
|
|
|
|
|
|
|
|
return sameRegion && notATutorialGame
|
|
|
|
|
})
|
2019-10-10 18:56:48 +00:00
|
|
|
|
2019-10-04 20:29:43 +00:00
|
|
|
return matchList
|
2019-10-01 19:39:26 +00:00
|
|
|
}
|
|
|
|
|
/**
|
2019-10-25 21:09:33 +00:00
|
|
|
* Update the full MatchList of the summoner (min. 4 months)
|
2019-10-01 19:39:26 +00:00
|
|
|
* @param account of the summoner
|
2019-10-25 21:09:33 +00:00
|
|
|
* @param summonerDB summoner in the database
|
2019-10-01 19:39:26 +00:00
|
|
|
*/
|
2019-10-25 21:09:33 +00:00
|
|
|
async updateMatchList(account, summonerDB) {
|
2019-10-03 19:52:36 +00:00
|
|
|
console.time('matchList')
|
2019-10-04 20:29:43 +00:00
|
|
|
|
2019-10-01 19:39:26 +00:00
|
|
|
// Summoner has already been searched : we already have a MatchList and we need to update it
|
2019-10-25 21:09:33 +00:00
|
|
|
if (summonerDB.matchList) {
|
2019-10-04 20:29:43 +00:00
|
|
|
// Get MatchList
|
|
|
|
|
const matchList = await this.fetchMatchListUntil(account, (newMatchList) => {
|
|
|
|
|
return summonerDB.matchList.some(m => m.gameId === newMatchList[newMatchList.length - 1].gameId)
|
|
|
|
|
})
|
2019-10-03 19:52:36 +00:00
|
|
|
// Update Summoner's MatchList
|
2019-10-06 15:31:43 +00:00
|
|
|
for (const match of matchList.reverse()) {
|
2019-10-03 19:52:36 +00:00
|
|
|
if (!summonerDB.matchList.some(m => m.gameId === match.gameId)) {
|
|
|
|
|
Logger.transport('file').info(`Match ${match.gameId} has been added to ${account.name}'s MatchList.`)
|
2019-10-06 15:31:43 +00:00
|
|
|
summonerDB.matchList.unshift(match)
|
2019-10-03 19:52:36 +00:00
|
|
|
}
|
|
|
|
|
}
|
2019-10-01 19:39:26 +00:00
|
|
|
Logger.transport('file').info(`Summoner ${account.name} has been updated.`)
|
|
|
|
|
}
|
|
|
|
|
// First search of the Summoner
|
|
|
|
|
else {
|
2019-10-04 20:29:43 +00:00
|
|
|
const today = Date.now()
|
|
|
|
|
// Get MatchList
|
|
|
|
|
const matchList = await this.fetchMatchListUntil(account, (newMatchList) => {
|
|
|
|
|
return (newMatchList.length !== 100 || today - newMatchList[newMatchList.length - 1].timestamp > 10368000000)
|
|
|
|
|
})
|
2019-10-25 21:09:33 +00:00
|
|
|
// Create Summoner's MatchList in Database
|
|
|
|
|
summonerDB.matchList = matchList
|
2019-10-01 19:39:26 +00:00
|
|
|
Logger.transport('file').info(`Summoner ${account.name} has been created.`)
|
|
|
|
|
}
|
2019-10-03 19:52:36 +00:00
|
|
|
console.timeEnd('matchList')
|
2019-10-01 19:39:26 +00:00
|
|
|
}
|
|
|
|
|
|
2019-10-05 18:01:01 +00:00
|
|
|
/**
|
|
|
|
|
* Fetch list of matches for a specific Summoner
|
|
|
|
|
* @param account of the summoner
|
|
|
|
|
* @param gameIds of the matches to fetch
|
2019-10-25 21:09:33 +00:00
|
|
|
* @param summonerDB summoner in the database
|
2019-10-05 18:01:01 +00:00
|
|
|
*/
|
2019-10-25 21:09:33 +00:00
|
|
|
async getMatches(account, gameIds, summonerDB) {
|
2019-10-05 18:01:01 +00:00
|
|
|
console.time('getMatches')
|
|
|
|
|
|
|
|
|
|
let matchesDetails = []
|
|
|
|
|
const matchesToGetFromRiot = []
|
|
|
|
|
for (let i = 0; i < gameIds.length; ++i) {
|
2019-10-26 20:52:50 +00:00
|
|
|
const matchSaved = await summonerDB.matches().where({ gameId: gameIds[i] }).first()
|
2019-10-05 18:01:01 +00:00
|
|
|
if (matchSaved) {
|
|
|
|
|
console.log('match in mongodb')
|
|
|
|
|
matchesDetails.push(matchSaved)
|
|
|
|
|
} else {
|
|
|
|
|
console.log('match to get from api')
|
|
|
|
|
matchesToGetFromRiot.push(gameIds[i])
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const requests = matchesToGetFromRiot.map(Jax.Match.get)
|
|
|
|
|
let matchesFromApi = await Promise.all(requests)
|
|
|
|
|
|
|
|
|
|
/* If we have to store some matches in the db */
|
|
|
|
|
if (matchesFromApi.length !== 0) {
|
2019-11-14 20:22:01 +00:00
|
|
|
const items = await Jax.DDragon.Item.list()
|
2019-10-05 18:01:01 +00:00
|
|
|
const champions = await Jax.DDragon.Champion.list()
|
|
|
|
|
const runes = await Jax.DDragon.Rune.list()
|
2019-11-14 20:22:01 +00:00
|
|
|
const version = Jax.DDragon.Version
|
2019-10-05 18:01:01 +00:00
|
|
|
const ctx = {
|
|
|
|
|
account,
|
|
|
|
|
champions: champions.data,
|
2019-11-14 20:22:01 +00:00
|
|
|
items: items.data,
|
2019-10-05 18:01:01 +00:00
|
|
|
runes,
|
2019-11-14 20:22:01 +00:00
|
|
|
version,
|
2019-10-05 18:01:01 +00:00
|
|
|
MatchHelper: this
|
|
|
|
|
}
|
|
|
|
|
|
2019-11-03 17:49:58 +00:00
|
|
|
matchesFromApi = matchesFromApi.map(m => {
|
|
|
|
|
if (m) return BasicMatchTransformer.transform(m, ctx)
|
|
|
|
|
})
|
|
|
|
|
|
|
|
|
|
console.log(matchesFromApi.length)
|
|
|
|
|
Logger.transport('file').info(matchesFromApi)
|
|
|
|
|
|
2019-10-05 18:01:01 +00:00
|
|
|
matchesDetails = [...matchesDetails, ...matchesFromApi]
|
|
|
|
|
|
|
|
|
|
/* Save all matches from Riot Api in db */
|
|
|
|
|
for (const match of matchesFromApi) {
|
2019-10-26 20:52:50 +00:00
|
|
|
await summonerDB.matches().create(match)
|
2019-10-05 18:01:01 +00:00
|
|
|
console.log('match saved')
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* Sort matches */
|
|
|
|
|
matchesDetails.sort((a, b) => (a.date < b.date) ? 1 : -1)
|
|
|
|
|
console.timeEnd('getMatches')
|
|
|
|
|
|
|
|
|
|
return matchesDetails
|
|
|
|
|
}
|
|
|
|
|
|
2019-10-01 19:39:26 +00:00
|
|
|
/**
|
|
|
|
|
* Return the lane of the summoner according to timeline
|
|
|
|
|
* @param timeline from Riot Api
|
|
|
|
|
*/
|
|
|
|
|
getRoleName(timeline) {
|
|
|
|
|
if (timeline.lane === 'BOTTOM' && timeline.role.includes('SUPPORT')) {
|
|
|
|
|
return 'SUPPORT'
|
|
|
|
|
}
|
|
|
|
|
return timeline.lane
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Return time in a formatted way
|
|
|
|
|
* @param sec time in seconds to convert
|
|
|
|
|
*/
|
|
|
|
|
secToTime(sec) {
|
|
|
|
|
const min = Math.floor(sec / 60)
|
|
|
|
|
const newSec = sec - min * 60
|
|
|
|
|
return min + 'm' + (newSec < 10 ? '0' + newSec : newSec) + 's'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Sort array of Roles according to a specific order
|
|
|
|
|
* @param a first role
|
|
|
|
|
* @param b second role
|
|
|
|
|
*/
|
|
|
|
|
sortTeamByRole(a, b) {
|
|
|
|
|
const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'SUPPORT']
|
|
|
|
|
return sortingArr.indexOf(a.role) - sortingArr.indexOf(b.role)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
module.exports = new MatchHelper()
|