2020-10-05 09:16:21 +00:00
|
|
|
import Jax from './Jax'
|
2021-08-07 20:52:54 +00:00
|
|
|
import { MatchlistDto } from './Jax/src/Endpoints/MatchlistEndpoint'
|
2021-09-20 17:20:51 +00:00
|
|
|
import Database from '@ioc:Adonis/Lucid/Database'
|
|
|
|
|
import MatchParser from 'App/Parsers/MatchParser'
|
|
|
|
|
import BasicMatchSerializer from 'App/Serializers/BasicMatchSerializer'
|
|
|
|
|
import { SerializedMatch } from 'App/Serializers/SerializedTypes'
|
|
|
|
|
import Match from 'App/Models/Match'
|
|
|
|
|
import { notEmpty, tutorialQueues } from 'App/helpers'
|
2022-02-01 22:16:58 +00:00
|
|
|
import SummonerMatchlist from 'App/Models/SummonerMatchlist'
|
|
|
|
|
|
|
|
|
|
export enum MatchListMode {
|
|
|
|
|
FIRSTIME = 'firstTime',
|
|
|
|
|
UPDATE = 'update',
|
|
|
|
|
LIGHT = 'light',
|
|
|
|
|
}
|
2020-10-05 09:16:21 +00:00
|
|
|
|
|
|
|
|
class MatchService {
|
|
|
|
|
/**
|
|
|
|
|
* Add 100 matches at a time to MatchList until the stopFetching condition is true
|
2022-02-01 22:16:58 +00:00
|
|
|
* @param puuid of the summoner
|
2021-09-20 17:20:51 +00:00
|
|
|
* @param region of the summoner
|
2020-10-05 09:16:21 +00:00
|
|
|
* @param stopFetching condition to stop fetching the MatchList
|
|
|
|
|
*/
|
2022-02-01 22:16:58 +00:00
|
|
|
private async _fetchMatchListUntil(puuid: string, region: string, stopFetching: any) {
|
2021-08-07 20:52:54 +00:00
|
|
|
let matchList: MatchlistDto = []
|
2020-10-05 09:16:21 +00:00
|
|
|
let alreadyIn = false
|
|
|
|
|
let index = 0
|
|
|
|
|
do {
|
2021-09-24 20:25:28 +00:00
|
|
|
console.log('--> CALL TO RIOT MATCHLIST')
|
2022-02-01 22:16:58 +00:00
|
|
|
const newMatchList = await Jax.Matchlist.puuid(puuid, region, index)
|
2020-10-05 09:16:21 +00:00
|
|
|
// Error while fetching Riot API
|
|
|
|
|
if (!newMatchList) {
|
|
|
|
|
return matchList
|
|
|
|
|
}
|
2021-08-07 20:52:54 +00:00
|
|
|
matchList = [...matchList, ...newMatchList]
|
|
|
|
|
alreadyIn = newMatchList.length === 0 || stopFetching(newMatchList)
|
2020-10-05 09:16:21 +00:00
|
|
|
// If the match is made in another region : we stop fetching
|
2021-09-20 17:20:51 +00:00
|
|
|
if (matchList[matchList.length - 1].split('_')[0].toLowerCase() !== region.toLowerCase()) {
|
|
|
|
|
alreadyIn = true
|
|
|
|
|
}
|
2020-10-05 09:16:21 +00:00
|
|
|
index += 100
|
|
|
|
|
} while (!alreadyIn)
|
|
|
|
|
return matchList
|
|
|
|
|
}
|
2022-02-01 22:16:58 +00:00
|
|
|
|
2020-10-05 09:16:21 +00:00
|
|
|
/**
|
2022-02-01 22:16:58 +00:00
|
|
|
* Update the MatchList of the summoner
|
2020-10-05 09:16:21 +00:00
|
|
|
*/
|
2021-09-20 17:20:51 +00:00
|
|
|
public async updateMatchList(
|
2022-02-01 22:16:58 +00:00
|
|
|
puuid: string,
|
2021-09-20 17:20:51 +00:00
|
|
|
region: string,
|
2022-02-01 22:16:58 +00:00
|
|
|
fetchMode: MatchListMode
|
2021-09-20 17:20:51 +00:00
|
|
|
): Promise<MatchlistDto> {
|
2020-10-05 09:16:21 +00:00
|
|
|
console.time('matchList')
|
|
|
|
|
|
2022-02-01 22:16:58 +00:00
|
|
|
const currentMatchList = await SummonerMatchlist.query()
|
|
|
|
|
.where('summoner_puuid', puuid)
|
|
|
|
|
.orderBy('matchId', 'asc')
|
2021-09-20 17:20:51 +00:00
|
|
|
const currentMatchListIds = currentMatchList.map((m) => m.matchId)
|
|
|
|
|
|
2022-02-01 22:16:58 +00:00
|
|
|
// Condition to stop fetching the matchlist
|
|
|
|
|
function stopFetching(newMatchList: MatchlistDto) {
|
|
|
|
|
switch (fetchMode) {
|
|
|
|
|
case MatchListMode.FIRSTIME:
|
|
|
|
|
return false
|
|
|
|
|
case MatchListMode.UPDATE:
|
|
|
|
|
return currentMatchListIds.some((id) => id === newMatchList[newMatchList.length - 1])
|
|
|
|
|
case MatchListMode.LIGHT:
|
|
|
|
|
default:
|
|
|
|
|
return true
|
2021-09-20 17:20:51 +00:00
|
|
|
}
|
2022-02-01 22:16:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
console.time('RiotMatchList')
|
|
|
|
|
const newMatchList = await this._fetchMatchListUntil(puuid, region, stopFetching)
|
2021-09-24 20:25:28 +00:00
|
|
|
console.timeEnd('RiotMatchList')
|
2021-09-20 17:20:51 +00:00
|
|
|
|
|
|
|
|
const matchListToSave: MatchlistDto = []
|
|
|
|
|
for (const matchId of newMatchList.reverse()) {
|
|
|
|
|
if (!currentMatchListIds.some((id) => id === matchId)) {
|
|
|
|
|
matchListToSave.push(matchId)
|
|
|
|
|
currentMatchListIds.push(matchId)
|
2020-10-05 09:16:21 +00:00
|
|
|
}
|
|
|
|
|
}
|
2021-09-20 17:20:51 +00:00
|
|
|
|
|
|
|
|
// If there is new matchIds to save in database
|
|
|
|
|
if (matchListToSave.length) {
|
|
|
|
|
await Database.table('summoner_matchlist').multiInsert(
|
|
|
|
|
matchListToSave.map((id) => ({
|
|
|
|
|
match_id: id,
|
2022-02-01 22:16:58 +00:00
|
|
|
summoner_puuid: puuid,
|
2021-09-20 17:20:51 +00:00
|
|
|
}))
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
|
2020-10-05 09:16:21 +00:00
|
|
|
console.timeEnd('matchList')
|
2021-09-20 17:20:51 +00:00
|
|
|
return currentMatchListIds.reverse()
|
2020-10-05 09:16:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Fetch list of matches for a specific Summoner
|
|
|
|
|
*/
|
2021-09-20 17:20:51 +00:00
|
|
|
public async getMatches(
|
|
|
|
|
region: string,
|
|
|
|
|
matchIds: string[],
|
|
|
|
|
puuid: string
|
|
|
|
|
): Promise<SerializedMatch[]> {
|
2020-10-08 07:51:12 +00:00
|
|
|
console.time('getMatches')
|
2020-10-05 09:16:21 +00:00
|
|
|
|
2021-09-20 17:20:51 +00:00
|
|
|
const matches: SerializedMatch[] = []
|
2021-08-10 22:12:17 +00:00
|
|
|
const matchesToGetFromRiot: MatchlistDto = []
|
2021-08-07 20:52:54 +00:00
|
|
|
for (let i = 0; i < matchIds.length; ++i) {
|
2021-09-20 17:20:51 +00:00
|
|
|
const matchSaved = await Match.query()
|
|
|
|
|
.where('id', matchIds[i])
|
|
|
|
|
.preload('teams')
|
|
|
|
|
.preload('players')
|
|
|
|
|
.first()
|
|
|
|
|
|
2020-10-08 07:51:12 +00:00
|
|
|
if (matchSaved) {
|
2021-09-20 17:20:51 +00:00
|
|
|
// TODO: Serialize match from DB + put it in Redis + push it in "matches"
|
|
|
|
|
matches.push(BasicMatchSerializer.serializeOneMatch(matchSaved, puuid))
|
2020-10-08 07:51:12 +00:00
|
|
|
} else {
|
2021-08-07 20:52:54 +00:00
|
|
|
matchesToGetFromRiot.push(matchIds[i])
|
2020-10-08 07:51:12 +00:00
|
|
|
}
|
|
|
|
|
}
|
2020-10-05 09:16:21 +00:00
|
|
|
|
2021-09-20 17:20:51 +00:00
|
|
|
const requests = matchesToGetFromRiot.map((gameId) => Jax.Match.get(gameId, region))
|
|
|
|
|
const matchesFromApi = await Promise.all(requests)
|
2020-10-05 09:16:21 +00:00
|
|
|
|
2020-10-08 07:51:12 +00:00
|
|
|
/* If we have to store some matches in the db */
|
|
|
|
|
if (matchesFromApi.length !== 0) {
|
2021-09-20 17:20:51 +00:00
|
|
|
// Remove bugged matches from the Riot API + tutorial games
|
|
|
|
|
const filteredMatches = matchesFromApi
|
|
|
|
|
.filter(notEmpty)
|
|
|
|
|
.filter(
|
|
|
|
|
(m) =>
|
|
|
|
|
!tutorialQueues.includes(m.info.queueId) &&
|
|
|
|
|
m.info.teams.length > 0 &&
|
2022-02-27 14:24:46 +00:00
|
|
|
m.info.participants.length > 0 &&
|
|
|
|
|
m.info.gameMode !== 'PRACTICETOOL'
|
2021-09-20 17:20:51 +00:00
|
|
|
)
|
2020-10-05 09:16:21 +00:00
|
|
|
|
2020-10-08 07:51:12 +00:00
|
|
|
// Transform raw matches data
|
2021-09-20 17:20:51 +00:00
|
|
|
const parsedMatches: any = await MatchParser.parse(filteredMatches)
|
2020-10-05 09:16:21 +00:00
|
|
|
|
2021-09-20 17:20:51 +00:00
|
|
|
// TODO: Serialize match from DB + put it in Redis + push it in "matches"
|
|
|
|
|
const serializedMatches = BasicMatchSerializer.serialize(parsedMatches, puuid, true)
|
|
|
|
|
matches.push(...serializedMatches)
|
2020-10-08 07:51:12 +00:00
|
|
|
}
|
2020-10-05 09:16:21 +00:00
|
|
|
|
2021-09-20 17:20:51 +00:00
|
|
|
// Todo: check if we need to sort here
|
|
|
|
|
matches.sort((a, b) => (a.date < b.date ? 1 : -1))
|
2020-10-08 07:51:12 +00:00
|
|
|
console.timeEnd('getMatches')
|
2021-09-20 17:20:51 +00:00
|
|
|
return matches
|
2020-10-08 07:51:12 +00:00
|
|
|
}
|
2020-10-05 09:16:21 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default new MatchService()
|