tauri-app: use fields from recorded raw league data
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
All checks were successful
record-daemon / Build, check and test (push) Successful in 2m6s
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { ref, onMounted } from "vue";
|
||||
import { invoke } from "@tauri-apps/api/core";
|
||||
import type { GameHistoryItem, TimestampedEvent, ItemInfo, RawEndGameStats, EndGamePlayer } from "../types/timeline";
|
||||
import type { GameHistoryItem, TimestampedEvent, ItemInfo } from "../types/timeline";
|
||||
import {
|
||||
getGameResult,
|
||||
formatDuration,
|
||||
@@ -16,6 +16,15 @@ import {
|
||||
formatGameStartTime,
|
||||
getSummonerSpellUrl,
|
||||
getItemImageUrl,
|
||||
getChampionName,
|
||||
getSummonerName,
|
||||
getQueueType,
|
||||
getQueueId,
|
||||
getGameMode,
|
||||
getMapName,
|
||||
getFinalStats,
|
||||
getSummonerSpells,
|
||||
getItems,
|
||||
} from "../types/timeline";
|
||||
|
||||
// Helper to get video timestamp in seconds from tuple format
|
||||
@@ -49,58 +58,9 @@ function closeDetail() {
|
||||
selectedGame.value = null;
|
||||
}
|
||||
|
||||
// Helper to find local player from raw end game stats
|
||||
function getLocalPlayer(stats: RawEndGameStats | null): EndGamePlayer | null {
|
||||
if (!stats) return null;
|
||||
|
||||
// Try localPlayer field first (camelCase from API)
|
||||
if (stats.localPlayer) {
|
||||
return stats.localPlayer;
|
||||
}
|
||||
|
||||
// Try teams
|
||||
if (stats.teams) {
|
||||
for (const team of stats.teams) {
|
||||
if (team.players) {
|
||||
for (const player of team.players) {
|
||||
if (player.isLocalPlayer) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try legacy players array
|
||||
if (stats.players && stats.players.length > 0) {
|
||||
return stats.players[0];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Helper to get items array for display (6 slots + trinket)
|
||||
// Items are now stored as raw item IDs in raw_end_game_stats
|
||||
function getItemsArray(game: GameHistoryItem): (ItemInfo | null)[] {
|
||||
const result: (ItemInfo | null)[] = [null, null, null, null, null, null, null];
|
||||
|
||||
const localPlayer = getLocalPlayer(game.raw_end_game_stats);
|
||||
if (localPlayer && localPlayer.items) {
|
||||
// Items are stored as an array of item IDs (up to 7 items: 6 main + 1 trinket)
|
||||
for (let i = 0; i < Math.min(localPlayer.items.length, 7); i++) {
|
||||
const itemId = localPlayer.items[i];
|
||||
if (itemId && itemId > 0) {
|
||||
// Slot 6 is trinket, slots 0-5 are main items
|
||||
result[i] = {
|
||||
itemId: itemId,
|
||||
name: null,
|
||||
slot: i
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
return getItems(game);
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
@@ -161,13 +121,13 @@ onMounted(() => {
|
||||
<div class="champion-section">
|
||||
<div class="champion-image-wrapper">
|
||||
<img
|
||||
:src="getChampionImageUrl(game.champion)"
|
||||
:alt="game.champion || 'Unknown Champion'"
|
||||
:src="getChampionImageUrl(getChampionName(game))"
|
||||
:alt="getChampionName(game) || 'Unknown Champion'"
|
||||
class="champion-image"
|
||||
@error="($event.target as HTMLImageElement).src = getChampionImageUrl(null)"
|
||||
/>
|
||||
<div class="champion-level" v-if="game.final_stats">
|
||||
{{ Math.min(18, Math.floor(game.final_stats.game_duration / 60)) }}
|
||||
<div class="champion-level" v-if="getFinalStats(game)">
|
||||
{{ Math.min(18, Math.floor(getFinalStats(game)!.game_duration / 60)) }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -175,18 +135,18 @@ onMounted(() => {
|
||||
<div class="summoner-spells">
|
||||
<div class="spell-slot">
|
||||
<img
|
||||
v-if="game.summoner_spells"
|
||||
:src="getSummonerSpellUrl(game.summoner_spells.spell1Id)"
|
||||
:alt="game.summoner_spells.spell1Name || 'Spell 1'"
|
||||
v-if="getSummonerSpells(game)"
|
||||
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell1Id)"
|
||||
:alt="getSummonerSpells(game)!.spell1Name || 'Spell 1'"
|
||||
class="spell-image"
|
||||
/>
|
||||
<div v-else class="spell-placeholder"></div>
|
||||
</div>
|
||||
<div class="spell-slot">
|
||||
<img
|
||||
v-if="game.summoner_spells"
|
||||
:src="getSummonerSpellUrl(game.summoner_spells.spell2Id)"
|
||||
:alt="game.summoner_spells.spell2Name || 'Spell 2'"
|
||||
v-if="getSummonerSpells(game)"
|
||||
:src="getSummonerSpellUrl(getSummonerSpells(game)!.spell2Id)"
|
||||
:alt="getSummonerSpells(game)!.spell2Name || 'Spell 2'"
|
||||
class="spell-image"
|
||||
/>
|
||||
<div v-else class="spell-placeholder"></div>
|
||||
@@ -200,7 +160,7 @@ onMounted(() => {
|
||||
<!-- Left: Queue Type & Time -->
|
||||
<div class="game-info-left">
|
||||
<div class="queue-type">
|
||||
{{ getQueueDisplayName(game.queue_type, game.queue_id) }}
|
||||
{{ getQueueDisplayName(getQueueType(game), getQueueId(game)) }}
|
||||
</div>
|
||||
<div class="game-duration">
|
||||
{{ formatDuration(game.duration_secs) }}
|
||||
@@ -211,12 +171,12 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<!-- Right: KDA Score -->
|
||||
<div class="kda-section" v-if="game.final_stats">
|
||||
<div class="kda-section" v-if="getFinalStats(game)">
|
||||
<span class="kda-values">
|
||||
{{ formatKDA(game.final_stats) }}
|
||||
{{ formatKDA(getFinalStats(game)) }}
|
||||
</span>
|
||||
<span class="kda-ratio" :class="{ perfect: game.final_stats.deaths === 0 }">
|
||||
{{ calculateKDA(game.final_stats) }} KDA
|
||||
<span class="kda-ratio" :class="{ perfect: getFinalStats(game)!.deaths === 0 }">
|
||||
{{ calculateKDA(getFinalStats(game)) }} KDA
|
||||
</span>
|
||||
</div>
|
||||
<div class="kda-section" v-else>
|
||||
@@ -227,15 +187,15 @@ onMounted(() => {
|
||||
</div>
|
||||
|
||||
<!-- Right: Key Stats Column + Items -->
|
||||
<div class="stats-section" v-if="game.final_stats">
|
||||
<div class="stats-section" v-if="getFinalStats(game)">
|
||||
<!-- Key Stats Column -->
|
||||
<div class="key-stats-column">
|
||||
<div class="key-stat">
|
||||
<span class="key-stat-value">{{ formatCSPerMin(game.final_stats) }}</span>
|
||||
<span class="key-stat-value">{{ formatCSPerMin(getFinalStats(game)) }}</span>
|
||||
<span class="key-stat-label">CS/m</span>
|
||||
</div>
|
||||
<div class="key-stat">
|
||||
<span class="key-stat-value">{{ formatGoldPerMin(game.final_stats) }}</span>
|
||||
<span class="key-stat-value">{{ formatGoldPerMin(getFinalStats(game)) }}</span>
|
||||
<span class="key-stat-label">Gold/m</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -277,14 +237,14 @@ onMounted(() => {
|
||||
<div class="modal-header">
|
||||
<div class="modal-champion">
|
||||
<img
|
||||
:src="getChampionImageUrl(selectedGame.champion)"
|
||||
:alt="selectedGame.champion || 'Unknown Champion'"
|
||||
:src="getChampionImageUrl(getChampionName(selectedGame))"
|
||||
:alt="getChampionName(selectedGame) || 'Unknown Champion'"
|
||||
class="modal-champion-image"
|
||||
/>
|
||||
<div class="modal-champion-info">
|
||||
<h2>{{ selectedGame.champion || 'Unknown Champion' }}</h2>
|
||||
<h2>{{ getChampionName(selectedGame) || 'Unknown Champion' }}</h2>
|
||||
<div class="modal-queue">
|
||||
{{ getQueueDisplayName(selectedGame.queue_type, selectedGame.queue_id) }}
|
||||
{{ getQueueDisplayName(getQueueType(selectedGame), getQueueId(selectedGame)) }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -306,66 +266,62 @@ onMounted(() => {
|
||||
<span class="detail-label">Started:</span>
|
||||
<span class="detail-value">{{ formatGameStartTime(selectedGame.start_time) }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.game_mode">
|
||||
<div class="detail-row" v-if="getGameMode(selectedGame)">
|
||||
<span class="detail-label">Game Mode:</span>
|
||||
<span class="detail-value">{{ selectedGame.game_mode }}</span>
|
||||
<span class="detail-value">{{ getGameMode(selectedGame) }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.map_name">
|
||||
<div class="detail-row" v-if="getMapName(selectedGame)">
|
||||
<span class="detail-label">Map:</span>
|
||||
<span class="detail-value">{{ selectedGame.map_name }}</span>
|
||||
<span class="detail-value">{{ getMapName(selectedGame) }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.summoner_name">
|
||||
<div class="detail-row" v-if="getSummonerName(selectedGame)">
|
||||
<span class="detail-label">Summoner:</span>
|
||||
<span class="detail-value">{{ selectedGame.summoner_name }}</span>
|
||||
</div>
|
||||
<div class="detail-row" v-if="selectedGame.team">
|
||||
<span class="detail-label">Team:</span>
|
||||
<span class="detail-value">{{ selectedGame.team === 100 ? 'Blue' : 'Red' }}</span>
|
||||
<span class="detail-value">{{ getSummonerName(selectedGame) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Stats -->
|
||||
<div class="modal-section" v-if="selectedGame.final_stats">
|
||||
<div class="modal-section" v-if="getFinalStats(selectedGame)">
|
||||
<h3>Performance</h3>
|
||||
<div class="stats-highlight">
|
||||
<div class="stat-highlight-item">
|
||||
<span class="stat-highlight-value">{{ selectedGame.final_stats.kills }}</span>
|
||||
<span class="stat-highlight-value">{{ getFinalStats(selectedGame)!.kills }}</span>
|
||||
<span class="stat-highlight-label">Kills</span>
|
||||
</div>
|
||||
<div class="stat-highlight-item">
|
||||
<span class="stat-highlight-value">{{ selectedGame.final_stats.deaths }}</span>
|
||||
<span class="stat-highlight-value">{{ getFinalStats(selectedGame)!.deaths }}</span>
|
||||
<span class="stat-highlight-label">Deaths</span>
|
||||
</div>
|
||||
<div class="stat-highlight-item">
|
||||
<span class="stat-highlight-value">{{ selectedGame.final_stats.assists }}</span>
|
||||
<span class="stat-highlight-value">{{ getFinalStats(selectedGame)!.assists }}</span>
|
||||
<span class="stat-highlight-label">Assists</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="detail-grid">
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">KDA Ratio:</span>
|
||||
<span class="detail-value">{{ calculateKDA(selectedGame.final_stats) }}</span>
|
||||
<span class="detail-value">{{ calculateKDA(getFinalStats(selectedGame)) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Creep Score:</span>
|
||||
<span class="detail-value">{{ selectedGame.final_stats.creep_score }} ({{ formatCSPerMin(selectedGame.final_stats) }}/min)</span>
|
||||
<span class="detail-value">{{ getFinalStats(selectedGame)!.creep_score }} ({{ formatCSPerMin(getFinalStats(selectedGame)) }}/min)</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Gold Earned:</span>
|
||||
<span class="detail-value">{{ formatNumber(selectedGame.final_stats.gold_earned) }} ({{ formatGoldPerMin(selectedGame.final_stats) }}/min)</span>
|
||||
<span class="detail-value">{{ formatNumber(getFinalStats(selectedGame)!.gold_earned) }} ({{ formatGoldPerMin(getFinalStats(selectedGame)) }}/min)</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Damage Dealt:</span>
|
||||
<span class="detail-value">{{ formatNumber(selectedGame.final_stats.damage_dealt) }}</span>
|
||||
<span class="detail-value">{{ formatNumber(getFinalStats(selectedGame)!.damage_dealt) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Damage Taken:</span>
|
||||
<span class="detail-value">{{ formatNumber(selectedGame.final_stats.damage_taken) }}</span>
|
||||
<span class="detail-value">{{ formatNumber(getFinalStats(selectedGame)!.damage_taken) }}</span>
|
||||
</div>
|
||||
<div class="detail-row">
|
||||
<span class="detail-label">Vision Score:</span>
|
||||
<span class="detail-value">{{ selectedGame.final_stats.vision_score.toFixed(1) }}</span>
|
||||
<span class="detail-value">{{ getFinalStats(selectedGame)!.vision_score.toFixed(1) }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -119,6 +119,7 @@ export type GameResult = 'Victory' | 'Defeat' | 'Terminated';
|
||||
/**
|
||||
* A timeline of events for a recording.
|
||||
* This is the main data structure returned by the backend.
|
||||
* Stores raw API responses for maximum flexibility.
|
||||
*/
|
||||
export interface Timeline {
|
||||
/** Recording ID (UUID). */
|
||||
@@ -132,49 +133,23 @@ export interface Timeline {
|
||||
/** Events in the timeline. */
|
||||
events: TimestampedEvent[];
|
||||
|
||||
// Player information
|
||||
/** Champion played. */
|
||||
champion: string | null;
|
||||
/** Skin name. */
|
||||
skin_name: string | null;
|
||||
/** Player's summoner name. */
|
||||
summoner_name: string | null;
|
||||
/** Player's PUUID. */
|
||||
puuid: string | null;
|
||||
/** Team (100 = blue, 200 = red). */
|
||||
team: number | null;
|
||||
|
||||
// Game information
|
||||
/** Queue type (ranked, normal, aram, etc.). */
|
||||
queue_type: string | null;
|
||||
/** Queue ID. */
|
||||
queue_id: number | null;
|
||||
/** Game mode. */
|
||||
game_mode: string | null;
|
||||
/** Map name. */
|
||||
map_name: string | null;
|
||||
/** Game ID. */
|
||||
game_id: number | null;
|
||||
/** Match ID. */
|
||||
match_id: string | null;
|
||||
|
||||
// Result
|
||||
/** Whether the game was won. */
|
||||
victory: boolean | null;
|
||||
/** Final player stats. */
|
||||
final_stats: GameFinalStats | null;
|
||||
|
||||
// Player metadata (runes, summoner spells, items)
|
||||
/** Rune page at game start. */
|
||||
runes: RunePage | null;
|
||||
/** Summoner spells. */
|
||||
summoner_spells: SummonerSpells | null;
|
||||
/** Raw end-of-game stats JSON from the API. */
|
||||
raw_end_game_stats: RawEndGameStats | null;
|
||||
|
||||
// All players in the game (puuid to summoner name mapping)
|
||||
/** All players in the game. */
|
||||
all_players: PlayerIdentityInfo[];
|
||||
// Raw API responses - frontend can parse these as needed
|
||||
/** Raw session data from `/lol-gameflow/v1/session`. */
|
||||
raw_session: Record<string, unknown> | null;
|
||||
/** Raw summoner data from `/lol-summoner/v1/current-summoner`. */
|
||||
raw_summoner: Record<string, unknown> | null;
|
||||
/** Raw champion select data from `/lol-champ-select/v1/session`. */
|
||||
raw_champion_select: Record<string, unknown> | null;
|
||||
/** Raw rune page data from `/lol-perks/v1/currentpage`. */
|
||||
raw_rune_page: Record<string, unknown> | null;
|
||||
/** Raw live client data from `/liveclientdata/allgamedata`. */
|
||||
raw_live_client_data: Record<string, unknown> | null;
|
||||
/** Raw end-of-game stats from `/lol-end-of-game/v1/eog-stats-block`. */
|
||||
raw_end_game_stats: Record<string, unknown> | null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -257,13 +232,166 @@ export type GameHistoryItem = Timeline;
|
||||
|
||||
/**
|
||||
* Get the game result as a display string.
|
||||
* Extracts from raw_end_game_stats.
|
||||
*/
|
||||
export function getGameResult(game: GameHistoryItem): GameResult {
|
||||
if (game.victory === true) return 'Victory';
|
||||
if (game.victory === false) return 'Defeat';
|
||||
// Try to extract victory from raw_end_game_stats
|
||||
const stats = game.raw_end_game_stats as RawEndGameStats | null;
|
||||
if (stats?.localPlayer?.stats?.WIN === 1) return 'Victory';
|
||||
if (stats?.localPlayer?.stats?.WIN === 0) return 'Defeat';
|
||||
return 'Terminated';
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract champion name from raw API data.
|
||||
*/
|
||||
export function getChampionName(game: GameHistoryItem): string | null {
|
||||
// Try raw_end_game_stats first (most reliable)
|
||||
const endStats = game.raw_end_game_stats as { localPlayer?: { championName?: string } } | null;
|
||||
if (endStats?.localPlayer?.championName) {
|
||||
return endStats.localPlayer.championName;
|
||||
}
|
||||
|
||||
// Try raw_live_client_data
|
||||
const liveData = game.raw_live_client_data as { activePlayer?: { championName?: string } } | null;
|
||||
if (liveData?.activePlayer?.championName) {
|
||||
return liveData.activePlayer.championName;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract summoner name from raw API data.
|
||||
*/
|
||||
export function getSummonerName(game: GameHistoryItem): string | null {
|
||||
// Try raw_end_game_stats first (most reliable for Riot ID)
|
||||
const endStats = game.raw_end_game_stats as { localPlayer?: { riotIdGameName?: string; riotIdTagLine?: string } } | null;
|
||||
if (endStats?.localPlayer?.riotIdGameName) {
|
||||
const tagLine = endStats.localPlayer.riotIdTagLine;
|
||||
return tagLine ? `${endStats.localPlayer.riotIdGameName}#${tagLine}` : endStats.localPlayer.riotIdGameName;
|
||||
}
|
||||
|
||||
// Try raw_summoner
|
||||
const summoner = game.raw_summoner as { displayName?: string; gameName?: string; tagLine?: string; name?: string } | null;
|
||||
if (summoner?.gameName) {
|
||||
const tagLine = summoner.tagLine;
|
||||
return tagLine ? `${summoner.gameName}#${tagLine}` : summoner.gameName;
|
||||
}
|
||||
return summoner?.displayName || summoner?.name || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract queue type from raw session data.
|
||||
*/
|
||||
export function getQueueType(game: GameHistoryItem): string | null {
|
||||
const session = game.raw_session as { gameData?: { queue?: { name?: string } } } | null;
|
||||
return session?.gameData?.queue?.name || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract queue ID from raw session data.
|
||||
*/
|
||||
export function getQueueId(game: GameHistoryItem): number | null {
|
||||
const session = game.raw_session as { gameData?: { queue?: { id?: number } } } | null;
|
||||
return session?.gameData?.queue?.id || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract game mode from raw session data.
|
||||
*/
|
||||
export function getGameMode(game: GameHistoryItem): string | null {
|
||||
const session = game.raw_session as { gameData?: { queue?: { gameMode?: string } } } | null;
|
||||
return session?.gameData?.queue?.gameMode || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract map name from raw session data.
|
||||
*/
|
||||
export function getMapName(game: GameHistoryItem): string | null {
|
||||
const session = game.raw_session as { map?: { name?: string } } | null;
|
||||
return session?.map?.name || null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract final stats from raw end game stats.
|
||||
*/
|
||||
export function getFinalStats(game: GameHistoryItem): GameFinalStats | null {
|
||||
const stats = game.raw_end_game_stats as RawEndGameStats | null;
|
||||
const player = stats?.localPlayer;
|
||||
const playerStats = player?.stats;
|
||||
|
||||
if (!playerStats) return null;
|
||||
|
||||
return {
|
||||
kills: playerStats.CHAMPIONS_KILLED || 0,
|
||||
deaths: playerStats.NUM_DEATHS || 0,
|
||||
assists: playerStats.ASSISTS || 0,
|
||||
creep_score: playerStats.MINIONS_KILLED || 0,
|
||||
gold_earned: playerStats.GOLD_EARNED || 0,
|
||||
damage_dealt: playerStats.TOTAL_DAMAGE_DEALT_TO_CHAMPIONS || 0,
|
||||
damage_taken: playerStats.TOTAL_DAMAGE_TAKEN || 0,
|
||||
vision_score: playerStats.VISION_SCORE || 0,
|
||||
game_duration: stats?.gameLength || 0,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract summoner spells from raw live client data.
|
||||
*/
|
||||
export function getSummonerSpells(game: GameHistoryItem): SummonerSpells | null {
|
||||
const liveData = game.raw_live_client_data as {
|
||||
activePlayer?: {
|
||||
summonerSpells?: {
|
||||
summonerSpellOne?: { spellId?: number; displayName?: string };
|
||||
summonerSpellTwo?: { spellId?: number; displayName?: string };
|
||||
spell1Id?: number;
|
||||
spell2Id?: number;
|
||||
}
|
||||
}
|
||||
} | null;
|
||||
|
||||
const spells = liveData?.activePlayer?.summonerSpells;
|
||||
if (!spells) return null;
|
||||
|
||||
const spell1Id = spells.summonerSpellOne?.spellId || spells.spell1Id || 0;
|
||||
const spell2Id = spells.summonerSpellTwo?.spellId || spells.spell2Id || 0;
|
||||
|
||||
if (spell1Id === 0 && spell2Id === 0) return null;
|
||||
|
||||
return {
|
||||
spell1Id,
|
||||
spell2Id,
|
||||
spell1Name: spells.summonerSpellOne?.displayName || null,
|
||||
spell2Name: spells.summonerSpellTwo?.displayName || null,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract items from raw end game stats.
|
||||
*/
|
||||
export function getItems(game: GameHistoryItem): (ItemInfo | null)[] {
|
||||
const result: (ItemInfo | null)[] = [null, null, null, null, null, null, null];
|
||||
|
||||
const stats = game.raw_end_game_stats as RawEndGameStats | null;
|
||||
const items = stats?.localPlayer?.items;
|
||||
|
||||
if (items) {
|
||||
for (let i = 0; i < Math.min(items.length, 7); i++) {
|
||||
const itemId = items[i];
|
||||
if (itemId && itemId > 0) {
|
||||
result[i] = {
|
||||
itemId,
|
||||
name: null,
|
||||
slot: i,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the result color class.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user