feat: added more stats

This commit is contained in:
TrèsAbhi committed 2024-03-20 16:58:43 -05:00
1 parent 38af2f2817
commit 21bafa1b7b
9 files changed
+103 -94

No files matched your search

+1 -1
View File
@@ -156,7 +156,7 @@ for (const leaderboardChunk of chunk(leaderboard, 100)) {
hits: stat.statistics.rating!.hits,
kills: stat.statistics.rating!.frags,
shots: stat.statistics.rating!.shots,
survived: stat.statistics.rating!.win_and_survived,
survived: stat.statistics.rating!.survived_battles,
wins: stat.statistics.rating!.wins,
};
});
+1 -1
View File
@@ -51,7 +51,7 @@ export interface ClanStats {
dropped_capture_points: number;
}
interface RatingStats {
export interface RatingStats {
spotted: number;
calibration_battles_left: number;
hits: number;
+15 -13
View File
@@ -1,7 +1,9 @@
import { RatingsInfo } from '../../commands/ratings';
import { Region } from '../../constants/regions';
import { asset } from './asset';
import { superDecompress } from './superDecompress';
const INFO_CACHE: Record<
const cache: Record<
Region,
Record<
number,
@@ -19,18 +21,18 @@ export default async function getArchivedRatingsInfo(
region: Region,
season: number,
) {
if (INFO_CACHE[region][season]) {
return INFO_CACHE[region][season];
if (!cache[region][season]) {
const info = await fetch(
asset(`regions/${region}/ratings/${season}/info.cdon.lz4`),
)
.then((response) => response.arrayBuffer())
.then((buffer) =>
superDecompress<RatingsInfo & { detail: undefined }>(
new Uint8Array(buffer),
),
);
cache[region][season] = info;
}
const response = await fetch(
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-assets/main/regions/${region}/ratings/${season}/info.json`,
);
const jsonContent = (await response.json()) as RatingsInfo & {
detail: undefined;
};
INFO_CACHE[region][season] = jsonContent;
return jsonContent;
return cache[region][season];
}
@@ -1,10 +1,8 @@
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
import { Region } from '../../constants/regions';
import { BkrlDiscriminatedEntries, BkrlReadStream } from '../streams/bkrl';
import { asset } from './asset';
const LEADERBOARD_CACHE: Record<
Region,
Record<number, BlitzkriegRatingsLeaderboard>
> = {
const cache: Record<Region, Record<number, BkrlDiscriminatedEntries>> = {
asia: {},
eu: {},
com: {},
@@ -14,15 +12,14 @@ export async function getArchivedRatingsLeaderboard(
region: Region,
season: number,
) {
if (LEADERBOARD_CACHE[region][season]) {
return LEADERBOARD_CACHE[region][season];
if (!cache[region][season]) {
const info = await fetch(
asset(`regions/${region}/ratings/${season}/latest.bkrl`),
)
.then((response) => response.arrayBuffer())
.then((buffer) => new BkrlReadStream(buffer).bkrl());
cache[region][season] = info;
}
const response = await fetch(
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-assets/main/regions/${region}/ratings/${season}/latest.json`,
);
const json = (await response.json()) as BlitzkriegRatingsLeaderboard;
LEADERBOARD_CACHE[region][season] = json;
return json;
return cache[region][season];
}
@@ -1,10 +1,8 @@
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
import { Region } from '../../constants/regions';
import { BkrlDiscriminatedEntries, BkrlReadStream } from '../streams/bkrl';
import { asset } from './asset';
const MIDNIGHT_LEADERBOARD_CACHE: Record<
Region,
Record<number, BlitzkriegRatingsLeaderboard>
> = {
const cache: Record<Region, Record<number, BkrlDiscriminatedEntries | null>> = {
com: {},
eu: {},
asia: {},
@@ -14,21 +12,18 @@ export default async function getArchivedRatingsMidnightLeaderboard(
region: Region,
season: number,
) {
if (MIDNIGHT_LEADERBOARD_CACHE[region][season]) {
return MIDNIGHT_LEADERBOARD_CACHE[region][season];
if (!cache[region][season]) {
const info = await fetch(
asset(`regions/${region}/ratings/${season}/midnight.bkrl`),
)
.then((response) =>
response.status === 404 ? null : response.arrayBuffer(),
)
.then((buffer) =>
buffer === null ? null : new BkrlReadStream(buffer).bkrl(),
);
cache[region][season] = info;
}
try {
const response = await fetch(
`https://raw.githubusercontent.com/tresabhi/blitzkrieg-assets/main/regions/${region}/ratings/${season}/midnight.json`,
);
const json = (await response.json()) as BlitzkriegRatingsLeaderboard;
MIDNIGHT_LEADERBOARD_CACHE[region][season] = json;
return json;
} catch (error) {
console.warn(
`No midnight leaderboard found for season ${season}, region ${region}`,
);
}
return cache[region][season];
}
@@ -0,0 +1,18 @@
import { RatingStats } from '../blitz/getAccountInfo';
import { BkrlComprehensive1Entry, BkrlMinimalEntry } from '../streams/bkrl';
export function deltaBkrlBlitzStats(
a: BkrlComprehensive1Entry,
b: RatingStats,
) {
return {
battles: b.battles - a.battles,
damageDealt: b.damage_dealt - a.damageDealt,
damageReceived: b.damage_received - a.damageReceived,
hits: b.hits - a.hits,
kills: b.frags - a.kills,
shots: b.shots - a.shots,
survived: b.survived_battles - a.survived,
wins: b.wins - a.wins,
} satisfies Omit<BkrlComprehensive1Entry, keyof BkrlMinimalEntry>;
}
+35 -40
View File
@@ -5,60 +5,55 @@ import {
} from '../../types/tanksStats';
export function deltaTankStats(
a: NormalizedTankStats,
b: NormalizedTankStats,
aRaw: NormalizedTankStats,
bRaw: NormalizedTankStats,
time?: number,
) {
const bTanks = Object.keys(b);
const bTanks = Object.keys(bRaw);
const changedTanks = bTanks.filter((id) => {
return (
a[id as unknown as number]?.all.battles !==
b[id as unknown as number].all.battles &&
aRaw[id as unknown as number]?.all.battles !==
bRaw[id as unknown as number].all.battles &&
(time === undefined
? true
: b[id as unknown as number].last_battle_time > time)
: bRaw[id as unknown as number].last_battle_time > time)
);
});
const diff = changedTanks.map((id) => {
const aTank = a[id as unknown as number] ?? emptyIndividualTankStats;
const bTank = b[id as unknown as number];
const a = aRaw[id as unknown as number] ?? emptyIndividualTankStats;
const b = bRaw[id as unknown as number];
const tankDiff = {
account_id: bTank.account_id,
battle_life_time: bTank.battle_life_time,
frags: (bTank.frags ?? aTank.frags ?? 0) - (aTank.frags ?? 0),
max_frags: Math.max(aTank.max_frags, bTank.max_frags),
in_garage: bTank.in_garage,
max_xp: Math.max(aTank.max_xp, bTank.max_xp),
in_garage_updated: bTank.in_garage_updated,
last_battle_time: Math.max(
bTank.last_battle_time,
aTank.last_battle_time,
),
mark_of_mastery: bTank.mark_of_mastery,
tank_id: bTank.tank_id,
account_id: b.account_id,
battle_life_time: b.battle_life_time,
frags: (b.frags ?? a.frags ?? 0) - (a.frags ?? 0),
max_frags: Math.max(a.max_frags, b.max_frags),
in_garage: b.in_garage,
max_xp: Math.max(a.max_xp, b.max_xp),
in_garage_updated: b.in_garage_updated,
last_battle_time: Math.max(b.last_battle_time, a.last_battle_time),
mark_of_mastery: b.mark_of_mastery,
tank_id: b.tank_id,
all: {
battles: bTank.all.battles - aTank.all.battles,
wins: bTank.all.wins - aTank.all.wins,
capture_points: bTank.all.capture_points - aTank.all.capture_points,
damage_dealt: bTank.all.damage_dealt - aTank.all.damage_dealt,
damage_received: bTank.all.damage_received - aTank.all.damage_received,
battles: b.all.battles - a.all.battles,
wins: b.all.wins - a.all.wins,
capture_points: b.all.capture_points - a.all.capture_points,
damage_dealt: b.all.damage_dealt - a.all.damage_dealt,
damage_received: b.all.damage_received - a.all.damage_received,
dropped_capture_points:
bTank.all.dropped_capture_points - aTank.all.dropped_capture_points,
frags: bTank.all.frags - aTank.all.frags,
frags8p: bTank.all.frags8p - aTank.all.frags8p,
hits: bTank.all.hits - aTank.all.hits,
losses: bTank.all.losses - aTank.all.losses,
max_frags: Math.max(aTank.max_frags, bTank.max_frags),
max_xp: Math.max(aTank.max_xp, bTank.max_xp),
shots: bTank.all.shots - aTank.all.shots,
spotted: bTank.all.spotted - aTank.all.spotted,
survived_battles:
bTank.all.survived_battles - aTank.all.survived_battles,
win_and_survived:
bTank.all.win_and_survived - aTank.all.win_and_survived,
xp: bTank.all.xp - aTank.all.xp,
b.all.dropped_capture_points - a.all.dropped_capture_points,
frags: b.all.frags - a.all.frags,
frags8p: b.all.frags8p - a.all.frags8p,
hits: b.all.hits - a.all.hits,
losses: b.all.losses - a.all.losses,
max_frags: Math.max(a.max_frags, b.max_frags),
max_xp: Math.max(a.max_xp, b.max_xp),
shots: b.all.shots - a.all.shots,
spotted: b.all.spotted - a.all.spotted,
survived_battles: b.all.survived_battles - a.all.survived_battles,
win_and_survived: b.all.win_and_survived - a.all.win_and_survived,
xp: b.all.xp - a.all.xp,
},
} satisfies IndividualTankStats;
+5 -5
View File
@@ -28,7 +28,7 @@ export interface BkrlComprehensive1Entry {
kills: number;
}
type DiscriminatedEntries =
export type BkrlDiscriminatedEntries =
| {
format: BkrlFormat.Minimal;
entries: BkrlMinimalEntry[];
@@ -45,7 +45,7 @@ export class BkrlReadStream extends ReadStream {
return this.body(header);
}
body(header: ReturnType<typeof this.header>): DiscriminatedEntries {
body(header: ReturnType<typeof this.header>): BkrlDiscriminatedEntries {
switch (header.format) {
case BkrlFormat.Minimal: {
return {
@@ -107,13 +107,13 @@ export class BkrlReadStream extends ReadStream {
}
export class BkrlWriteStream extends WriteStream {
bkrl(discriminatedEntries: DiscriminatedEntries) {
bkrl(discriminatedEntries: BkrlDiscriminatedEntries) {
this.magic();
this.header(discriminatedEntries);
this.body(discriminatedEntries);
}
body(discriminatedEntries: DiscriminatedEntries) {
body(discriminatedEntries: BkrlDiscriminatedEntries) {
switch (discriminatedEntries.format) {
case BkrlFormat.Minimal: {
discriminatedEntries.entries.forEach((entry) => {
@@ -145,7 +145,7 @@ export class BkrlWriteStream extends WriteStream {
}
}
header(discriminatedEntries: DiscriminatedEntries) {
header(discriminatedEntries: BkrlDiscriminatedEntries) {
this.uint16(1);
this.uint8(discriminatedEntries.format);
this.uint32(discriminatedEntries.entries.length);
+2
View File
@@ -30,6 +30,7 @@ import { researchCommand } from '../../commands/research';
import { searchClansCommand } from '../../commands/searchClans';
import { searchPlayersCommand } from '../../commands/searchPlayers';
import { statsCommand } from '../../commands/stats';
import { testCommand } from '../../commands/test';
import { todayCommand } from '../../commands/today';
import getClientId from '../../core/blitzkrieg/getClientId';
import isDev from '../../core/blitzkrieg/isDev';
@@ -95,6 +96,7 @@ export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
ratingsCommand,
todayCommand,
researchCommand,
testCommand,
];
export const commands = Promise.allSettled(COMMANDS_RAW).then((rawCommands) => {