2022-01-30 17:01:05 +00:00
|
|
|
import Database, { TransactionClientContract } from '@ioc:Adonis/Lucid/Database'
|
2021-09-12 18:18:19 +00:00
|
|
|
import { MatchDto } from 'App/Services/Jax/src/Endpoints/MatchEndpoint'
|
2021-09-12 21:24:21 +00:00
|
|
|
import Match from 'App/Models/Match'
|
2021-09-14 14:03:08 +00:00
|
|
|
import { getSeasonNumber, queuesWithRole } from 'App/helpers'
|
2021-09-13 22:06:12 +00:00
|
|
|
import CDragonService from 'App/Services/CDragonService'
|
2021-09-14 14:03:08 +00:00
|
|
|
import { ChampionRoles, TeamPosition } from './ParsedType'
|
2021-09-12 18:18:19 +00:00
|
|
|
class MatchParser {
|
|
|
|
|
public async parseOneMatch(match: MatchDto) {
|
2022-01-30 17:01:05 +00:00
|
|
|
let parsedMatch: Match | null = null
|
|
|
|
|
let trx: TransactionClientContract | undefined
|
2021-09-12 21:24:21 +00:00
|
|
|
|
2022-01-30 17:01:05 +00:00
|
|
|
try {
|
|
|
|
|
// Start transaction
|
|
|
|
|
trx = await Database.transaction()
|
2021-09-13 20:06:12 +00:00
|
|
|
|
2022-01-30 17:01:05 +00:00
|
|
|
const gameDuration =
|
|
|
|
|
match.info.gameDuration > 100_000
|
|
|
|
|
? Math.round(match.info.gameDuration / 1000)
|
|
|
|
|
: match.info.gameDuration
|
2021-09-13 20:06:12 +00:00
|
|
|
|
2022-01-30 17:01:05 +00:00
|
|
|
const isRemake = gameDuration < 300
|
2021-09-12 21:24:21 +00:00
|
|
|
|
2022-01-30 17:01:05 +00:00
|
|
|
// - 1x Match
|
|
|
|
|
parsedMatch = await Match.create(
|
|
|
|
|
{
|
|
|
|
|
id: match.metadata.matchId,
|
|
|
|
|
gameId: match.info.gameId,
|
|
|
|
|
map: match.info.mapId,
|
|
|
|
|
gamemode: match.info.queueId,
|
|
|
|
|
date: match.info.gameCreation,
|
|
|
|
|
region: match.info.platformId.toLowerCase(),
|
|
|
|
|
result: match.info.teams[0].win ? match.info.teams[0].teamId : match.info.teams[1].teamId,
|
|
|
|
|
season: getSeasonNumber(match.info.gameCreation),
|
|
|
|
|
gameDuration,
|
|
|
|
|
},
|
|
|
|
|
{ client: trx }
|
|
|
|
|
)
|
2021-09-12 22:17:53 +00:00
|
|
|
|
2022-01-30 17:01:05 +00:00
|
|
|
// - 2x MatchTeam : Red and Blue
|
|
|
|
|
for (const team of match.info.teams) {
|
|
|
|
|
let result = team.win ? 'Win' : 'Fail'
|
|
|
|
|
if (isRemake) {
|
|
|
|
|
result = 'Remake'
|
2021-09-13 20:06:12 +00:00
|
|
|
}
|
2022-01-30 17:01:05 +00:00
|
|
|
await parsedMatch.related('teams').create({
|
|
|
|
|
matchId: match.metadata.matchId,
|
|
|
|
|
color: team.teamId,
|
|
|
|
|
result: result,
|
|
|
|
|
barons: team.objectives.baron.kills,
|
|
|
|
|
dragons: team.objectives.dragon.kills,
|
|
|
|
|
inhibitors: team.objectives.inhibitor.kills,
|
|
|
|
|
riftHeralds: team.objectives.riftHerald.kills,
|
|
|
|
|
towers: team.objectives.tower.kills,
|
|
|
|
|
bans: team.bans.length ? team.bans.map((ban) => ban.championId) : undefined,
|
|
|
|
|
banOrders: team.bans.length ? team.bans.map((ban) => ban.pickTurn) : undefined,
|
|
|
|
|
})
|
2021-09-13 20:06:12 +00:00
|
|
|
}
|
2021-09-12 22:17:53 +00:00
|
|
|
|
2022-01-30 17:01:05 +00:00
|
|
|
// - 10x MatchPlayer
|
|
|
|
|
const matchPlayers: any[] = []
|
|
|
|
|
for (const player of match.info.participants) {
|
|
|
|
|
const kda =
|
|
|
|
|
player.kills + player.assists !== 0 && player.deaths === 0
|
|
|
|
|
? player.kills + player.assists
|
|
|
|
|
: +(player.deaths === 0 ? 0 : (player.kills + player.assists) / player.deaths).toFixed(
|
|
|
|
|
2
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
const team =
|
|
|
|
|
match.info.teams[0].teamId === player.teamId ? match.info.teams[0] : match.info.teams[1]
|
|
|
|
|
const teamKills = team.objectives.champion.kills
|
|
|
|
|
|
|
|
|
|
let kp =
|
|
|
|
|
teamKills === 0 ? 0 : +(((player.kills + player.assists) * 100) / teamKills).toFixed(1)
|
|
|
|
|
|
|
|
|
|
const primaryStyle = player.perks.styles.find((s) => s.description === 'primaryStyle')
|
|
|
|
|
const secondaryStyle = player.perks.styles.find((s) => s.description === 'subStyle')
|
|
|
|
|
|
|
|
|
|
const perksSelected: number[] = []
|
|
|
|
|
for (const styles of player.perks.styles) {
|
|
|
|
|
for (const perk of styles.selections) {
|
|
|
|
|
perksSelected.push(perk.perk)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Fix championId bug in older matches
|
|
|
|
|
if (player.championId > 1000) {
|
|
|
|
|
const championId = Object.keys(CDragonService.champions).find(
|
|
|
|
|
(key) =>
|
|
|
|
|
CDragonService.champions[key].name === player.championName ||
|
|
|
|
|
CDragonService.champions[key].alias === player.championName
|
2021-09-17 22:01:06 +00:00
|
|
|
)
|
2022-01-30 17:01:05 +00:00
|
|
|
if (!championId) {
|
|
|
|
|
console.log(
|
|
|
|
|
`CHAMPION NOT FOUND AT ALL: ${player.championId} FROM: ${match.metadata.matchId}`
|
|
|
|
|
)
|
|
|
|
|
}
|
|
|
|
|
player.championId = championId ? Number(championId) : 1
|
2021-09-17 22:01:06 +00:00
|
|
|
}
|
2022-01-30 17:01:05 +00:00
|
|
|
|
|
|
|
|
const originalChampionData = CDragonService.champions[player.championId]
|
|
|
|
|
const champRoles = originalChampionData.roles
|
|
|
|
|
|
|
|
|
|
matchPlayers.push({
|
|
|
|
|
match_id: match.metadata.matchId,
|
|
|
|
|
participant_id: player.participantId,
|
|
|
|
|
summoner_id: player.summonerId,
|
|
|
|
|
summoner_puuid: player.puuid,
|
|
|
|
|
summoner_name: player.summonerName,
|
|
|
|
|
win: team.win ? 1 : 0,
|
|
|
|
|
loss: team.win ? 0 : 1,
|
|
|
|
|
remake: isRemake ? 1 : 0,
|
|
|
|
|
team: player.teamId,
|
|
|
|
|
team_position:
|
|
|
|
|
player.teamPosition.length && queuesWithRole.includes(match.info.queueId)
|
|
|
|
|
? TeamPosition[player.teamPosition]
|
|
|
|
|
: TeamPosition.NONE,
|
|
|
|
|
kills: player.kills,
|
|
|
|
|
deaths: player.deaths,
|
|
|
|
|
assists: player.assists,
|
|
|
|
|
kda: kda,
|
|
|
|
|
kp: kp,
|
|
|
|
|
champ_level: player.champLevel,
|
|
|
|
|
champion_id: player.championId,
|
|
|
|
|
champion_role: ChampionRoles[champRoles[0]],
|
|
|
|
|
double_kills: player.doubleKills,
|
|
|
|
|
triple_kills: player.tripleKills,
|
|
|
|
|
quadra_kills: player.quadraKills,
|
|
|
|
|
penta_kills: player.pentaKills,
|
|
|
|
|
baron_kills: player.baronKills,
|
|
|
|
|
dragon_kills: player.dragonKills,
|
|
|
|
|
turret_kills: player.turretKills,
|
|
|
|
|
vision_score: player.visionScore,
|
|
|
|
|
gold: player.goldEarned,
|
|
|
|
|
summoner1_id: player.summoner1Id,
|
|
|
|
|
summoner2_id: player.summoner2Id,
|
|
|
|
|
item0: player.item0,
|
|
|
|
|
item1: player.item1,
|
|
|
|
|
item2: player.item2,
|
|
|
|
|
item3: player.item3,
|
|
|
|
|
item4: player.item4,
|
|
|
|
|
item5: player.item5,
|
|
|
|
|
item6: player.item6,
|
|
|
|
|
damage_dealt_objectives: player.damageDealtToObjectives,
|
|
|
|
|
damage_dealt_champions: player.totalDamageDealtToChampions,
|
|
|
|
|
damage_taken: player.totalDamageTaken,
|
|
|
|
|
heal: player.totalHeal,
|
|
|
|
|
minions: player.totalMinionsKilled + player.neutralMinionsKilled,
|
|
|
|
|
critical_strike: player.largestCriticalStrike,
|
|
|
|
|
killing_spree: player.killingSprees,
|
|
|
|
|
time_spent_living: player.longestTimeSpentLiving,
|
|
|
|
|
perks_primary_style: primaryStyle!.style,
|
|
|
|
|
perks_secondary_style: secondaryStyle!.style,
|
|
|
|
|
perks_selected: perksSelected.concat(Object.values(player.perks.statPerks)),
|
|
|
|
|
})
|
2021-09-14 14:03:08 +00:00
|
|
|
}
|
2022-01-30 17:01:05 +00:00
|
|
|
await Database.table('match_players').multiInsert(matchPlayers)
|
2021-09-14 14:03:08 +00:00
|
|
|
|
2022-01-30 17:01:05 +00:00
|
|
|
// Load Match relations
|
|
|
|
|
await parsedMatch.load((loader) => {
|
|
|
|
|
loader.load('teams').load('players')
|
2021-09-13 20:06:12 +00:00
|
|
|
})
|
2022-01-30 17:01:05 +00:00
|
|
|
|
|
|
|
|
if (!trx.isCompleted) {
|
|
|
|
|
await trx.commit()
|
|
|
|
|
}
|
|
|
|
|
} catch (error) {
|
|
|
|
|
console.log('Error in MatchParser transaction.')
|
|
|
|
|
if (trx && trx.isTransaction) {
|
|
|
|
|
await trx.rollback()
|
|
|
|
|
return null
|
|
|
|
|
}
|
2021-09-13 20:06:12 +00:00
|
|
|
}
|
2021-09-13 22:06:12 +00:00
|
|
|
|
2021-09-12 21:24:21 +00:00
|
|
|
return parsedMatch
|
2021-09-12 18:18:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public async parse(matches: MatchDto[]) {
|
2021-09-12 21:24:21 +00:00
|
|
|
const parsedMatches: Match[] = []
|
|
|
|
|
for (const match of matches) {
|
2022-01-30 17:01:05 +00:00
|
|
|
const parsed = await this.parseOneMatch(match)
|
|
|
|
|
if (parsed) {
|
|
|
|
|
parsedMatches.push(parsed)
|
|
|
|
|
}
|
2021-09-12 21:24:21 +00:00
|
|
|
}
|
|
|
|
|
return parsedMatches
|
2021-09-12 18:18:19 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export default new MatchParser()
|