Merge branch 'serializer' into V2

This commit is contained in:
Kalane 2021-09-13 22:08:49 +02:00
commit adf08ac779
5 changed files with 290 additions and 9 deletions

View file

@ -0,0 +1,152 @@
import { getSeasonNumber, sortTeamByRole } from 'App/helpers'
import Match from 'App/Models/Match'
import MatchPlayer from 'App/Models/MatchPlayer'
import MatchSerializer from './MatchSerializer'
import {
SerializedMatch,
SerializedMatchChampion,
SerializedMatchItem,
SerializedMatchPerks,
SerializedMatchStats,
SerializedMatchTeamPlayer,
} from './SerializedTypes'
class BasicMatchSerializer extends MatchSerializer {
/**
* Get champion specific data
* @param id of the champion
*/
protected getChampion(id: number): SerializedMatchChampion {
const originalChampionData = this.champions.find((c) => c.id === id)
const icon =
'https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/' +
originalChampionData!.squarePortraitPath.split('/assets/')[1].toLowerCase()
return {
icon,
id: originalChampionData!.id,
name: originalChampionData!.name,
alias: originalChampionData!.alias,
roles: originalChampionData!.roles,
}
}
protected getPlayerSummary(player: MatchPlayer): SerializedMatchTeamPlayer {
return {
puuid: player.summonerPuuid,
champion: this.getChampion(player.championId),
name: player.summonerName,
role: player.teamPosition,
}
}
protected getTeamSummary(players: MatchPlayer[]): SerializedMatchTeamPlayer[] {
return players.map((p) => this.getPlayerSummary(p)).sort(sortTeamByRole)
}
protected getItems(player: MatchPlayer): Array<SerializedMatchItem | null> {
const items: (SerializedMatchItem | null)[] = []
for (let i = 0; i < 6; i++) {
const id = player['item' + i]
if (id === 0) {
items.push(null)
continue
}
const item = this.items.find((i) => i.id === id)
if (!item) {
items.push(null)
continue
}
const itemUrl = item.iconPath.split('/assets/')[1].toLowerCase()
items.push({
image: `https://raw.communitydragon.org/latest/plugins/rcp-be-lol-game-data/global/default/${itemUrl}`,
name: item.name,
description: item.description,
price: item.priceTotal,
})
}
return items
}
protected getPerks(player: MatchPlayer): SerializedMatchPerks {
return {
primaryStyle: player.perksPrimaryStyle,
secondaryStyle: player.perksSecondaryStyle,
selected: player.perksSelected,
}
}
protected getStats(player: MatchPlayer): SerializedMatchStats {
return {
kills: player.kills,
deaths: player.deaths,
assists: player.assists,
minions: player.minions,
vision: player.visionScore,
gold: player.gold,
dmgChamp: player.damageDealtChampions,
dmgObj: player.damageDealtObjectives,
dmgTaken: player.damageTaken,
kp: player.kp,
kda: player.kills + player.assists !== 0 && player.deaths === 0 ? '∞' : player.kda,
realKda: player.kda,
criticalStrike: player.criticalStrike,
killingSpree: player.killingSpree,
doubleKills: player.doubleKills,
tripleKills: player.tripleKills,
quadraKills: player.quadraKills,
pentaKills: player.pentaKills,
heal: player.heal,
towers: player.turretKills,
longestLiving: player.timeSpentLiving,
}
}
public serializeOneMatch(match: Match, puuid: string): SerializedMatch {
const identity = match.players.find((p) => p.summonerPuuid === puuid)!
const allyTeamColor = identity.team === 100 ? 'blueTeam' : 'redTeam'
const allyTeam = match[allyTeamColor]
const allyPlayers: MatchPlayer[] = []
const enemyPlayers: MatchPlayer[] = []
for (const p of match.players) {
// TODO: remove Number() when Lazar push the updated migration
p.team === Number(allyTeam.color) ? allyPlayers.push(p) : enemyPlayers.push(p)
}
return {
allyTeam: this.getTeamSummary(allyPlayers),
champion: this.getChampion(identity.championId),
date: match.date,
enemyTeam: this.getTeamSummary(enemyPlayers),
firstSum: identity.summoner1Id,
matchId: match.id,
gamemode: match.gamemode,
items: this.getItems(identity),
level: identity.champLevel,
map: match.map,
name: identity.summonerName,
perks: this.getPerks(identity),
region: match.region,
result: allyTeam.result.toString(), // TODO: remove toString() when Lazar push the updated migration
role: identity.teamPosition,
season: getSeasonNumber(match.date),
secondSum: identity.summoner2Id,
stats: this.getStats(identity),
summonerId: identity.summonerId,
summonerPuuid: puuid,
time: match.gameDuration,
}
}
public async serialize(matches: Match[], puuid: string): Promise<SerializedMatch[]> {
await super.getContext()
return matches.map((match) => this.serializeOneMatch(match, puuid))
}
}
export default new BasicMatchSerializer()

View file

@ -0,0 +1,39 @@
import Jax from 'App/Services/Jax'
import {
ChampionDTO,
ItemDTO,
PerkDTO,
PerkStyleDTO,
SummonerSpellDTO,
} from 'App/Services/Jax/src/Endpoints/CDragonEndpoint'
import RoleIdentificationService, {
ChampionsPlayRate,
} from 'App/Services/RoleIdentificationService'
export default abstract class MatchSerializer {
protected champions: ChampionDTO[]
protected items: ItemDTO[]
protected perks: PerkDTO[]
protected perkstyles: PerkStyleDTO[]
protected summonerSpells: SummonerSpellDTO[]
protected championRoles: ChampionsPlayRate
/**
* Get global Context with CDragon Data
*/
public async getContext() {
const items = await Jax.CDragon.items()
const champions = await Jax.CDragon.champions()
const perks = await Jax.CDragon.perks()
const perkstyles = await Jax.CDragon.perkstyles()
const summonerSpells = await Jax.CDragon.summonerSpells()
const championRoles = await RoleIdentificationService.pullData().catch(() => {})
this.champions = champions
this.items = items
this.perks = perks
this.perkstyles = perkstyles.styles
this.summonerSpells = summonerSpells
this.championRoles = championRoles as ChampionsPlayRate
}
}

View file

@ -0,0 +1,75 @@
export interface SerializedMatch {
allyTeam: SerializedMatchTeamPlayer[]
champion: SerializedMatchChampion
date: number
enemyTeam: SerializedMatchTeamPlayer[]
firstSum: number
matchId: string
gamemode: number
items: Array<SerializedMatchItem | null>
level: number
map: number
name: string
perks: SerializedMatchPerks
region: string
result: string
role: string
season: number
secondSum: number
stats: SerializedMatchStats
summonerId: string
summonerPuuid: string
time: number
}
export interface SerializedMatchTeamPlayer {
puuid: string
champion: SerializedMatchChampion
name: string
role: string
}
export interface SerializedMatchChampion {
alias: string
icon: string
id: number
name: string
roles: string[]
}
export interface SerializedMatchItem {
description: string
image: string
name: string
price: number
}
export interface SerializedMatchPerks {
primaryStyle: number
secondaryStyle: number
selected: number[]
}
export interface SerializedMatchStats {
assists: number
criticalStrike: number
deaths: number
dmgChamp: number
dmgObj: number
dmgTaken: number
doubleKills: number
gold: number
heal: number
kda: number | string
killingSpree: number
kills: number
kp: number
longestLiving: number
minions: number
pentaKills: number
quadraKills: number
realKda: number
towers: number
tripleKills: number
vision: number
}

View file

@ -5,6 +5,8 @@ import Summoner from 'App/Models/Summoner'
import Database from '@ioc:Adonis/Lucid/Database' import Database from '@ioc:Adonis/Lucid/Database'
import SummonerMatchlist from 'App/Models/SummonerMatchlist' import SummonerMatchlist from 'App/Models/SummonerMatchlist'
import MatchParser from 'App/Parsers/MatchParser' import MatchParser from 'App/Parsers/MatchParser'
import BasicMatchSerializer from 'App/Serializers/BasicMatchSerializer'
import { SerializedMatch } from 'App/Serializers/SerializedTypes'
class MatchService { class MatchService {
/** /**
@ -76,21 +78,28 @@ class MatchService {
/** /**
* Fetch list of matches for a specific Summoner * Fetch list of matches for a specific Summoner
*/ */
public async getMatches(region: string, matchList: SummonerMatchlist[], summonerDB: Summoner) { public async getMatches(
region: string,
matchList: SummonerMatchlist[],
summonerDB: Summoner
): Promise<SerializedMatch[]> {
console.time('getMatches') console.time('getMatches')
let matches: any[] = [] // Todo: add type of serialized matches here let matches: SerializedMatch[] = []
const matchesToGetFromRiot: MatchlistDto = [] const matchesToGetFromRiot: MatchlistDto = []
for (let i = 0; i < matchList.length; ++i) { for (let i = 0; i < matchList.length; ++i) {
const matchSaved = await summonerDB const matchSaved = await summonerDB
.related('matches') .related('matches')
.query() .query()
.where('matchId', matchList[i].matchId) .where('matchId', matchList[i].matchId)
.preload('match') .preload('match', (preloader) => {
preloader.preload('blueTeam').preload('redTeam').preload('players')
})
.first() .first()
if (matchSaved) { if (matchSaved) {
// TODO: Serialize match from DB + put it in Redis + push it in "matches" // TODO: Serialize match from DB + put it in Redis + push it in "matches"
matches.push(BasicMatchSerializer.serializeOneMatch(matchSaved.match, summonerDB.puuid))
} else { } else {
matchesToGetFromRiot.push(matchList[i].matchId) matchesToGetFromRiot.push(matchList[i].matchId)
} }
@ -102,14 +111,20 @@ class MatchService {
/* If we have to store some matches in the db */ /* If we have to store some matches in the db */
if (matchesFromApi.length !== 0) { if (matchesFromApi.length !== 0) {
// Transform raw matches data // Transform raw matches data
const parsedMatches = await MatchParser.parse(matchesFromApi) const parsedMatches: any = await MatchParser.parse(matchesFromApi)
// TODO: Serialize match from DB + put it in Redis + push it in "matches" // TODO: Serialize match from DB + put it in Redis + push it in "matches"
const serializedMatches = await BasicMatchSerializer.serialize(
parsedMatches,
summonerDB.puuid
)
matches = [...matches, ...serializedMatches]
} }
// Todo: Sort and return "matches" // Todo: check if we need to sort here
matches.sort((a, b) => (a.date < b.date ? 1 : -1))
console.timeEnd('getMatches') console.timeEnd('getMatches')
return matches
} }
} }

View file

@ -1,4 +1,4 @@
import MatchPlayer from './Models/MatchPlayer' import { SerializedMatchTeamPlayer } from './Serializers/SerializedTypes'
/** /**
* All League of Legends regions used in Riot API * All League of Legends regions used in Riot API
@ -104,7 +104,7 @@ export function getCurrentSeason(): number {
* @param a first player * @param a first player
* @param b second player * @param b second player
*/ */
export function sortTeamByRole(a: MatchPlayer, b: MatchPlayer) { export function sortTeamByRole(a: SerializedMatchTeamPlayer, b: SerializedMatchTeamPlayer) {
const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'SUPPORT'] const sortingArr = ['TOP', 'JUNGLE', 'MIDDLE', 'BOTTOM', 'SUPPORT']
return sortingArr.indexOf(a.teamPosition) - sortingArr.indexOf(b.teamPosition) return sortingArr.indexOf(a.role) - sortingArr.indexOf(b.role)
} }