refactor/match_collector: refactor platform handling logic
This commit is contained in:
@@ -11,6 +11,7 @@ import {
|
||||
areTreeSimilars,
|
||||
treeDeriveTags
|
||||
} from './item_tree'
|
||||
import { PLATFORM_KEYS } from './platform'
|
||||
|
||||
import { Match, Timeline, Participant, Frame } from './api'
|
||||
|
||||
@@ -345,10 +346,10 @@ function handleMatch(match: Match, champions: Map<number, ChampionData>, platfor
|
||||
// Track region distribution for this lane
|
||||
if (lane.regionDistribution && platform) {
|
||||
const platformKey = platform.toLowerCase()
|
||||
if (platformKey === 'euw1') lane.regionDistribution.euw++
|
||||
else if (platformKey === 'eun1') lane.regionDistribution.eun++
|
||||
else if (platformKey === 'na1') lane.regionDistribution.na++
|
||||
else if (platformKey === 'kr') lane.regionDistribution.kr++
|
||||
const regionKey = PLATFORM_KEYS[platformKey]
|
||||
if (regionKey) {
|
||||
lane.regionDistribution[regionKey]!++
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize matchups if not present
|
||||
|
||||
@@ -5,22 +5,7 @@ import { MongoClient } from 'mongodb'
|
||||
|
||||
import champion_stat from './champion_stat'
|
||||
import { Match } from './api'
|
||||
|
||||
// Region configuration: platform -> regional routing value
|
||||
const PLATFORMS: Record<string, string> = {
|
||||
EUW1: 'EUROPE',
|
||||
EUN1: 'EUROPE',
|
||||
NA1: 'AMERICAS',
|
||||
KR: 'ASIA'
|
||||
}
|
||||
|
||||
function getPlatformBaseUrl(platform: string): string {
|
||||
return `https://${platform.toLowerCase()}.api.riotgames.com`
|
||||
}
|
||||
|
||||
function getRegionalBaseUrl(region: string): string {
|
||||
return `https://${region.toLowerCase()}.api.riotgames.com`
|
||||
}
|
||||
import { PLATFORMS, getPlatformBaseUrl, getRegionalBaseUrl, getRegionForPlatform } from './platform'
|
||||
|
||||
main()
|
||||
|
||||
@@ -75,7 +60,7 @@ async function main() {
|
||||
// Determine region from matchId (format: PLATFORM_matchId)
|
||||
// Map platform prefix to regional routing value for match API
|
||||
const matchPlatformPrefix = game.split('_')[0]
|
||||
const matchRegion = PLATFORMS[matchPlatformPrefix] || region
|
||||
const matchRegion = getRegionForPlatform(matchPlatformPrefix) || region
|
||||
const gameMatch = await match(game, matchRegion)
|
||||
const gameTimeline = await matchTimeline(game, matchRegion)
|
||||
gameMatch.timeline = gameTimeline
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
type GoldAdvantageTag = 'ahead' | 'behind' | 'even'
|
||||
import {
|
||||
PlatformCounts,
|
||||
REGION_KEYS,
|
||||
initPlatformCounts,
|
||||
mergePlatformCounts,
|
||||
singlePlatformCount
|
||||
} from './platform'
|
||||
|
||||
type PlatformCounts = {
|
||||
euw: number
|
||||
eun: number
|
||||
na: number
|
||||
kr: number
|
||||
}
|
||||
type GoldAdvantageTag = 'ahead' | 'behind' | 'even'
|
||||
|
||||
// Item tags that can be derived from purchase patterns
|
||||
type ItemTag = 'ahead' | 'behind' | 'region_euw' | 'region_eun' | 'region_na' | 'region_kr'
|
||||
@@ -30,10 +31,6 @@ type ItemTree = {
|
||||
tags: Array<ItemTag>
|
||||
}
|
||||
|
||||
function initPlatformCounts(): PlatformCounts {
|
||||
return { euw: 0, eun: 0, na: 0, kr: 0 }
|
||||
}
|
||||
|
||||
function treeInit(): ItemTree {
|
||||
return {
|
||||
data: undefined,
|
||||
@@ -63,10 +60,7 @@ function nodeMerge(itemtree: ItemTree, node: ItemTree) {
|
||||
child.boughtWhen.behindCount += node.boughtWhen.behindCount
|
||||
|
||||
// Merge platform counts
|
||||
child.platformCount.euw += node.platformCount.euw
|
||||
child.platformCount.eun += node.platformCount.eun
|
||||
child.platformCount.na += node.platformCount.na
|
||||
child.platformCount.kr += node.platformCount.kr
|
||||
mergePlatformCounts(child.platformCount, node.platformCount)
|
||||
|
||||
next = child
|
||||
break
|
||||
@@ -99,7 +93,6 @@ function treeMerge(
|
||||
let current = itemtree
|
||||
|
||||
for (const item of items) {
|
||||
const platformKey = item.platform ? item.platform.toLowerCase() : null
|
||||
current = nodeMerge(current, {
|
||||
data: item.itemId,
|
||||
count: 1,
|
||||
@@ -110,12 +103,7 @@ function treeMerge(
|
||||
meanGold: 0
|
||||
},
|
||||
children: [],
|
||||
platformCount: {
|
||||
euw: platformKey === 'euw1' ? 1 : 0,
|
||||
eun: platformKey === 'eun1' ? 1 : 0,
|
||||
na: platformKey === 'na1' ? 1 : 0,
|
||||
kr: platformKey === 'kr' ? 1 : 0
|
||||
},
|
||||
platformCount: item.platform ? singlePlatformCount(item.platform) : initPlatformCounts(),
|
||||
tags: []
|
||||
})
|
||||
}
|
||||
@@ -174,12 +162,7 @@ function treeClone(tree: ItemTree): ItemTree {
|
||||
evenCount: tree.boughtWhen.evenCount,
|
||||
meanGold: tree.boughtWhen.meanGold
|
||||
},
|
||||
platformCount: {
|
||||
euw: tree.platformCount.euw,
|
||||
eun: tree.platformCount.eun,
|
||||
na: tree.platformCount.na,
|
||||
kr: tree.platformCount.kr
|
||||
},
|
||||
platformCount: { ...tree.platformCount },
|
||||
tags: [...tree.tags]
|
||||
}
|
||||
}
|
||||
@@ -192,10 +175,7 @@ function treeMergeTree(t1: ItemTree, t2: ItemTree): ItemTree {
|
||||
t1.count += t2.count
|
||||
|
||||
// Merge platform counts
|
||||
t1.platformCount.euw += t2.platformCount.euw
|
||||
t1.platformCount.eun += t2.platformCount.eun
|
||||
t1.platformCount.na += t2.platformCount.na
|
||||
t1.platformCount.kr += t2.platformCount.kr
|
||||
mergePlatformCounts(t1.platformCount, t2.platformCount)
|
||||
|
||||
// Merge boughtWhen
|
||||
t1.boughtWhen.aheadCount += t2.boughtWhen.aheadCount
|
||||
@@ -302,44 +282,31 @@ function deriveTags(node: ItemTree, expectedRegionDistribution?: PlatformCounts)
|
||||
}
|
||||
|
||||
// Derive region tags by comparing against expected distribution
|
||||
const totalRegionCount =
|
||||
node.platformCount.euw + node.platformCount.eun + node.platformCount.na + node.platformCount.kr
|
||||
const totalRegionCount = REGION_KEYS.reduce((sum, key) => sum + node.platformCount[key], 0)
|
||||
if (totalRegionCount > 0 && expectedRegionDistribution) {
|
||||
const totalExpected =
|
||||
expectedRegionDistribution.euw +
|
||||
expectedRegionDistribution.eun +
|
||||
expectedRegionDistribution.na +
|
||||
expectedRegionDistribution.kr
|
||||
const totalExpected = REGION_KEYS.reduce((sum, key) => sum + expectedRegionDistribution[key], 0)
|
||||
|
||||
if (totalExpected > 0) {
|
||||
// Calculate expected percentages
|
||||
const expectedEuwPct = expectedRegionDistribution.euw / totalExpected
|
||||
const expectedEunPct = expectedRegionDistribution.eun / totalExpected
|
||||
const expectedNaPct = expectedRegionDistribution.na / totalExpected
|
||||
const expectedKrPct = expectedRegionDistribution.kr / totalExpected
|
||||
|
||||
// Calculate actual percentages for this item
|
||||
const actualEuwPct = node.platformCount.euw / totalRegionCount
|
||||
const actualEunPct = node.platformCount.eun / totalRegionCount
|
||||
const actualNaPct = node.platformCount.na / totalRegionCount
|
||||
const actualKrPct = node.platformCount.kr / totalRegionCount
|
||||
|
||||
// Tag if the item is significantly more popular in a region (>= 1.5x expected rate)
|
||||
// and has a minimum absolute percentage (>= 10%)
|
||||
const SIGNIFICANCE_THRESHOLD = 1.5
|
||||
const MINIMUM_PCT = 0.1
|
||||
|
||||
if (actualEuwPct >= expectedEuwPct * SIGNIFICANCE_THRESHOLD && actualEuwPct >= MINIMUM_PCT) {
|
||||
tags.push('region_euw')
|
||||
// Loop through all regions to derive tags
|
||||
const regionTags: Array<{ key: keyof PlatformCounts; tag: ItemTag }> = [
|
||||
{ key: 'euw', tag: 'region_euw' },
|
||||
{ key: 'eun', tag: 'region_eun' },
|
||||
{ key: 'na', tag: 'region_na' },
|
||||
{ key: 'kr', tag: 'region_kr' }
|
||||
]
|
||||
|
||||
for (const { key, tag } of regionTags) {
|
||||
const expectedPct = expectedRegionDistribution[key] / totalExpected
|
||||
const actualPct = node.platformCount[key] / totalRegionCount
|
||||
|
||||
if (actualPct >= expectedPct * SIGNIFICANCE_THRESHOLD && actualPct >= MINIMUM_PCT) {
|
||||
tags.push(tag)
|
||||
}
|
||||
if (actualEunPct >= expectedEunPct * SIGNIFICANCE_THRESHOLD && actualEunPct >= MINIMUM_PCT) {
|
||||
tags.push('region_eun')
|
||||
}
|
||||
if (actualNaPct >= expectedNaPct * SIGNIFICANCE_THRESHOLD && actualNaPct >= MINIMUM_PCT) {
|
||||
tags.push('region_na')
|
||||
}
|
||||
if (actualKrPct >= expectedKrPct * SIGNIFICANCE_THRESHOLD && actualKrPct >= MINIMUM_PCT) {
|
||||
tags.push('region_kr')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
104
match_collector/platform.ts
Normal file
104
match_collector/platform.ts
Normal file
@@ -0,0 +1,104 @@
|
||||
/**
|
||||
* Platform and region configuration for Riot Games API
|
||||
*
|
||||
* Platforms are the server clusters (EUW1, EUN1, NA1, KR)
|
||||
* Regions are the routing values for match API (EUROPE, AMERICAS, ASIA)
|
||||
*/
|
||||
|
||||
// Platform to regional routing value mapping
|
||||
const PLATFORMS: Record<string, string> = {
|
||||
EUW1: 'EUROPE',
|
||||
EUN1: 'EUROPE',
|
||||
NA1: 'AMERICAS',
|
||||
KR: 'ASIA'
|
||||
}
|
||||
|
||||
// Platform counts for tracking item purchases per region
|
||||
type PlatformCounts = {
|
||||
euw: number
|
||||
eun: number
|
||||
na: number
|
||||
kr: number
|
||||
}
|
||||
|
||||
// Platform key mapping for converting platform strings to PlatformCounts keys
|
||||
const PLATFORM_KEYS: Record<string, keyof PlatformCounts> = {
|
||||
euw1: 'euw',
|
||||
eun1: 'eun',
|
||||
na1: 'na',
|
||||
kr: 'kr'
|
||||
}
|
||||
|
||||
// List of all region keys for iteration
|
||||
const REGION_KEYS: Array<keyof PlatformCounts> = ['euw', 'eun', 'na', 'kr']
|
||||
|
||||
/**
|
||||
* Get the base URL for platform-specific API calls (e.g., league-v4)
|
||||
*/
|
||||
function getPlatformBaseUrl(platform: string): string {
|
||||
return `https://${platform.toLowerCase()}.api.riotgames.com`
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the base URL for regional API calls (e.g., match-v5)
|
||||
*/
|
||||
function getRegionalBaseUrl(region: string): string {
|
||||
return `https://${region.toLowerCase()}.api.riotgames.com`
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the regional routing value for a platform
|
||||
* Falls back to the provided default region if platform not found
|
||||
*/
|
||||
function getRegionForPlatform(platform: string): string | undefined {
|
||||
return PLATFORMS[platform]
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize an empty PlatformCounts object
|
||||
*/
|
||||
function initPlatformCounts(): PlatformCounts {
|
||||
return { euw: 0, eun: 0, na: 0, kr: 0 }
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge platform counts from source into target
|
||||
*/
|
||||
function mergePlatformCounts(target: PlatformCounts, source: PlatformCounts): void {
|
||||
for (const key of REGION_KEYS) {
|
||||
target[key] += source[key]
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a platform count with a single platform set to 1
|
||||
*/
|
||||
function singlePlatformCount(platform: string): PlatformCounts {
|
||||
const counts = initPlatformCounts()
|
||||
const key = PLATFORM_KEYS[platform.toLowerCase()]
|
||||
if (key) {
|
||||
counts[key] = 1
|
||||
}
|
||||
return counts
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the PlatformCounts key for a platform string
|
||||
*/
|
||||
function getPlatformKey(platform: string): keyof PlatformCounts | undefined {
|
||||
return PLATFORM_KEYS[platform.toLowerCase()]
|
||||
}
|
||||
|
||||
export {
|
||||
PLATFORMS,
|
||||
PlatformCounts,
|
||||
PLATFORM_KEYS,
|
||||
REGION_KEYS,
|
||||
getPlatformBaseUrl,
|
||||
getRegionalBaseUrl,
|
||||
getRegionForPlatform,
|
||||
initPlatformCounts,
|
||||
mergePlatformCounts,
|
||||
singlePlatformCount,
|
||||
getPlatformKey
|
||||
}
|
||||
Reference in New Issue
Block a user