mirror of
https://github.com/vkaelin/LeagueStats.git
synced 2026-03-25 12:57:28 +00:00
feat: use custom RoleIdentification if Riot roles are badly identified
This commit is contained in:
parent
5cd9b7600f
commit
c16974fcfb
5 changed files with 84 additions and 24 deletions
|
|
@ -4,7 +4,7 @@ const got = require('got')
|
|||
const Redis = use('Redis')
|
||||
|
||||
class RoleIdentificationService {
|
||||
_getPermutations (array) {
|
||||
_getPermutations(array) {
|
||||
const result = []
|
||||
|
||||
for (let i = 0; i < array.length; i++) {
|
||||
|
|
@ -21,13 +21,13 @@ class RoleIdentificationService {
|
|||
return result
|
||||
}
|
||||
|
||||
_calculateMetric (championPositions, bestPositions) {
|
||||
_calculateMetric(championPositions, bestPositions) {
|
||||
return Object.entries(bestPositions).reduce((agg, [position, champion]) => {
|
||||
return agg + (championPositions[champion][position] || 0)
|
||||
}, 0) / Object.keys(bestPositions).length
|
||||
}
|
||||
|
||||
_getPositions (championPositions, composition, top, jungle, middle, adc, support) {
|
||||
_getPositions(championPositions, composition, top, jungle, middle, adc, support) {
|
||||
// Set the initial guess to be the champion in the composition, order doesn't matter
|
||||
let bestPositions = {
|
||||
'TOP': composition[0],
|
||||
|
|
@ -104,7 +104,7 @@ class RoleIdentificationService {
|
|||
/**
|
||||
* Get the CDN data of the champion playrates by role
|
||||
*/
|
||||
async pullData () {
|
||||
async pullData() {
|
||||
const url = 'http://cdn.merakianalytics.com/riot/lol/resources/latest/en-US/championrates.json'
|
||||
|
||||
// Check if cached
|
||||
|
|
@ -144,13 +144,13 @@ class RoleIdentificationService {
|
|||
* @param composition
|
||||
* @param jungle
|
||||
*/
|
||||
getRoles (championPositions, composition, jungle = null) {
|
||||
getRoles(championPositions, composition, jungle = null) {
|
||||
const identified = {}
|
||||
let positions = {}
|
||||
let secondaryPositions = null
|
||||
let secondaryMetric = -Infinity
|
||||
|
||||
if(jungle) {
|
||||
if (jungle) {
|
||||
identified['JUNGLE'] = jungle
|
||||
}
|
||||
|
||||
|
|
@ -193,7 +193,13 @@ class RoleIdentificationService {
|
|||
identified[best[0]] = best[1]
|
||||
}
|
||||
|
||||
return positions
|
||||
// Rename UTILITY to SUPPORT
|
||||
const {
|
||||
UTILITY: SUPPORT,
|
||||
...rest
|
||||
} = positions
|
||||
|
||||
return { ...rest, SUPPORT }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use strict'
|
||||
|
||||
const MatchTransformer = use('App/Transformers/MatchTransformer')
|
||||
const { queuesWithRole } = use('App/helpers')
|
||||
|
||||
/**
|
||||
* BasicMatchTransformer class
|
||||
|
|
@ -65,8 +66,9 @@ class BasicMatchTransformer extends MatchTransformer {
|
|||
enemyTeam.push(playerInfos)
|
||||
}
|
||||
}
|
||||
allyTeam.sort(this.sortTeamByRole)
|
||||
enemyTeam.sort(this.sortTeamByRole)
|
||||
|
||||
// Roles
|
||||
super.getMatchRoles(match, allyTeam, enemyTeam, player.teamId, playerData)
|
||||
|
||||
return {
|
||||
account_id: identity.player.currentAccountId,
|
||||
|
|
|
|||
|
|
@ -23,6 +23,9 @@ class DetailedMatchTransformer extends MatchTransformer {
|
|||
const firstTeam = this.getTeamData(match, match.teams[0])
|
||||
const secondTeam = this.getTeamData(match, match.teams[1])
|
||||
|
||||
// Roles
|
||||
super.getMatchRoles(match, firstTeam.players, secondTeam.players)
|
||||
|
||||
return {
|
||||
gameId: match.gameId,
|
||||
season: match.seasonId,
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
'use strict'
|
||||
|
||||
const MatchTransformer = use('App/Transformers/MatchTransformer')
|
||||
const RoleIdentificationService = use('App/Services/RoleIdentificationService')
|
||||
const SummonerService = use('App/Services/SummonerService')
|
||||
const { queuesWithRole } = use('App/helpers')
|
||||
|
||||
|
|
@ -24,13 +23,6 @@ class LiveMatchTransformer extends MatchTransformer {
|
|||
return participant
|
||||
}
|
||||
|
||||
_getTeamRoles(team) {
|
||||
const teamJunglers = team.filter(p => p.jungle)
|
||||
const jungle = teamJunglers.length === 1 ? teamJunglers[0].champion : null
|
||||
|
||||
return RoleIdentificationService.getRoles(this.championRoles, team.map(p => p.champion), jungle)
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform raw data from Riot API
|
||||
* @param match data from Riot API, one live match
|
||||
|
|
@ -50,8 +42,8 @@ class LiveMatchTransformer extends MatchTransformer {
|
|||
p.teamId === 100 ? blueTeam.push(playerRole) : redTeam.push(playerRole)
|
||||
})
|
||||
|
||||
blueRoles = this._getTeamRoles(blueTeam)
|
||||
redRoles = this._getTeamRoles(redTeam)
|
||||
blueRoles = super.getTeamRoles(blueTeam)
|
||||
redRoles = super.getTeamRoles(redTeam)
|
||||
}
|
||||
|
||||
for (const participant of match.participants) {
|
||||
|
|
@ -62,9 +54,6 @@ class LiveMatchTransformer extends MatchTransformer {
|
|||
if (needsRole) {
|
||||
const roles = participant.teamId === 100 ? blueRoles : redRoles
|
||||
participant.role = Object.entries(roles).find(([, champion]) => participant.championId === champion)[0]
|
||||
if (participant.role === 'UTILITY') {
|
||||
participant.role = 'SUPPORT'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ class MatchTransformer {
|
|||
const perks = await Jax.CDragon.perks()
|
||||
const perkstyles = await Jax.CDragon.perkstyles()
|
||||
const summonerSpells = await Jax.CDragon.summonerSpells()
|
||||
const championRoles = await RoleIdentificationService.pullData().catch(() => {})
|
||||
const championRoles = await RoleIdentificationService.pullData().catch(() => { })
|
||||
|
||||
this.champions = champions
|
||||
this.items = items
|
||||
|
|
@ -196,7 +196,7 @@ class MatchTransformer {
|
|||
* @param gamemode of the match to check if a role is needed
|
||||
*/
|
||||
getRoleName(timeline, gamemode) {
|
||||
if(!queuesWithRole.includes(gamemode)) {
|
||||
if (!queuesWithRole.includes(gamemode)) {
|
||||
return 'NONE'
|
||||
}
|
||||
|
||||
|
|
@ -207,6 +207,66 @@ class MatchTransformer {
|
|||
return timeline.lane
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the 5 roles of a team based on champions
|
||||
* @param team 5 champions + smite from a team
|
||||
*/
|
||||
getTeamRoles(team) {
|
||||
const teamJunglers = team.filter(p => p.jungle)
|
||||
const jungle = teamJunglers.length === 1 ? teamJunglers[0].champion : null
|
||||
|
||||
return RoleIdentificationService.getRoles(this.championRoles, team.map(p => p.champion), jungle)
|
||||
}
|
||||
|
||||
/**
|
||||
* Update roles for a team if Riot's ones are badly identified
|
||||
* @param {Object} team 5 players data of the team
|
||||
* @param {Array} champs 5 champions + smite from the team
|
||||
* @param {Object} playerData data of the searched player, only for basic matches
|
||||
*/
|
||||
updateTeamRoles(team, champs, playerData = null) {
|
||||
const actualRoles = [...new Set(team.map(p => p.role))]
|
||||
if (actualRoles.length === 5) {
|
||||
return
|
||||
}
|
||||
|
||||
champs = this.getTeamRoles(champs)
|
||||
for (const summoner of team) {
|
||||
summoner.role = Object.entries(champs).find(([, champion]) => summoner.champion.id === champion)[0]
|
||||
|
||||
if (playerData && summoner.champion.id === playerData.champion.id) {
|
||||
playerData.role = summoner.role
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {Object} match from Riot Api
|
||||
* @param {Array} allyTeam 5 players of the first team
|
||||
* @param {Array} enemyTeam 5 players of the second team
|
||||
* @param {Number} allyTeamId team id of the searched player, only for basic matches
|
||||
* @param {Object} playerData data of the searched player, only for basic matches
|
||||
*/
|
||||
getMatchRoles(match, allyTeam, enemyTeam, allyTeamId = 100, playerData = null) {
|
||||
if (!this.championRoles || !queuesWithRole.includes(match.queueId)) {
|
||||
return
|
||||
}
|
||||
|
||||
let allyChamps = []
|
||||
let enemyChamps = []
|
||||
match.participants.map(p => {
|
||||
const playerRole = { champion: p.championId, jungle: p.spell1Id === 11 || p.spell2Id === 11 }
|
||||
p.teamId === allyTeamId ? allyChamps.push(playerRole) : enemyChamps.push(playerRole)
|
||||
})
|
||||
|
||||
this.updateTeamRoles(allyTeam, allyChamps, playerData)
|
||||
this.updateTeamRoles(enemyTeam, enemyChamps)
|
||||
|
||||
allyTeam.sort(this.sortTeamByRole)
|
||||
enemyTeam.sort(this.sortTeamByRole)
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Summoner Spell Data from CDragon
|
||||
* @param id of the summonerSpell
|
||||
|
|
|
|||
Loading…
Reference in a new issue