const base = "https://euw1.api.riotgames.com" const api_key = process.env.RIOT_API_KEY const sleep_minutes = 3 import { MongoClient } from 'mongodb' import champion_stat from "./champion_stat" main() async function main() { console.log("MatchCollector - Hello !"); const client = await connectToDatabase(); const [latestPatch, latestPatchTime] = await fetchLatestPatchDate(client); console.log("Connected to database, latest patch " + latestPatch + " was epoch: " + latestPatchTime) const alreadySeenGameList = await alreadySeenGames(client, latestPatch); console.log("We already have " + alreadySeenGameList.length + " matches for this patch !") if(process.env.RIOT_API_KEY != null && process.env.RIOT_API_KEY != undefined && process.env.RIOT_API_KEY != "") { const challengerLeague = await fetchChallengerLeague(); console.log("ChallengerLeague: got " + challengerLeague.entries.length + " entries"); const gameList = []; let i = 0; for(let challenger of challengerLeague.entries) { console.log("Entry " + i + "/" + challengerLeague.entries.length + " ...") const puuid = await summonerPuuid(challenger.summonerId); const challengerGameList = await summonerGameList(puuid, latestPatchTime); for(let game of challengerGameList) { if(!gameList.includes(game) && !alreadySeenGameList.includes(game)) { gameList.push(game) } } i++; } console.log("Games: got " + gameList.length + " entries"); i = 0; for(let game of gameList) { console.log("Entry " + i + "/" + gameList.length + " ...") const gameMatch = await match(game) const gameTimeline = await matchTimeline(game) gameMatch.timeline = gameTimeline await saveMatch(client, gameMatch, latestPatch) i++; } } console.log("Generating stats..."); await champion_stat.makeChampionsStats(client, latestPatch) console.log("All done. Closing client."); await client.close() } async function handleRateLimit(url : URL) : Promise { let response = await fetch(url) if(response.status == 429) { await new Promise(resolve => setTimeout(resolve, sleep_minutes * 60 * 1000)) response = await handleRateLimit(url) } return response } function handleError(response : Response) { if(!response.ok) { console.log("Error during fetch(" + response.url + "): STATUS " + response.status + " (" + response.statusText + ")"); process.exit(1); } } async function connectToDatabase() { // Create a MongoClient with a MongoClientOptions object to set the Stable API version const client = new MongoClient(`mongodb://${process.env.MONGO_USER}:${process.env.MONGO_PASS}@mongo:27017`) await client.connect() return client } async function fetchLatestPatchDate(client) { const database = client.db("patches"); const patches = database.collection("patches"); const latestPatch = await patches.find().limit(1).sort({date:-1}).next() return [latestPatch.patch, Math.floor(latestPatch.date.valueOf() / 1000)] } async function fetchChallengerLeague() { const queue = "RANKED_SOLO_5x5" const endpoint = `/lol/league/v4/challengerleagues/by-queue/${queue}` const url = `${base}${endpoint}?api_key=${api_key}` const challengerLeagueResponse = await handleRateLimit(new URL(url)); handleError(challengerLeagueResponse) const challengerLeague = await challengerLeagueResponse.json(); return challengerLeague; } async function summonerPuuid(summonerId) { const endpoint = `/lol/summoner/v4/summoners/${summonerId}` const url = `${base}${endpoint}?api_key=${api_key}` const puuidResponse = await handleRateLimit(new URL(url)); handleError(puuidResponse) const puuidJson = await puuidResponse.json(); return puuidJson.puuid; } async function summonerGameList(puuid, startTime) { const base = "https://europe.api.riotgames.com" const endpoint = `/lol/match/v5/matches/by-puuid/${puuid}/ids`; const url = `${base}${endpoint}?queue=420&type=ranked&startTime=${startTime}&api_key=${api_key}` const gameListResponse = await handleRateLimit(new URL(url)); handleError(gameListResponse) const gameList = await gameListResponse.json(); return gameList; } async function match(matchId) { const base = "https://europe.api.riotgames.com" const endpoint = `/lol/match/v5/matches/${matchId}` const url = `${base}${endpoint}?api_key=${api_key}` const matchResponse = await handleRateLimit(new URL(url)) handleError(matchResponse) const match = await matchResponse.json(); return match; } async function matchTimeline(matchId) { const base = "https://europe.api.riotgames.com" const endpoint = `/lol/match/v5/matches/${matchId}/timeline` const url = `${base}${endpoint}?api_key=${api_key}` const timelineResponse = await handleRateLimit(new URL(url)) handleError(timelineResponse) const timeline = await timelineResponse.json(); return timeline } async function alreadySeenGames(client, latestPatch) { const database = client.db("matches") const matches = database.collection(latestPatch) const alreadySeen = await matches.distinct("metadata.matchId") return alreadySeen } async function saveMatch(client, match, latestPatch) { const database = client.db("matches") const matches = database.collection(latestPatch) await matches.insertOne(match) }