mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 20:19:49 +02:00
feat: added more stats
This commit is contained in:
1 parent
38af2f2817
commit
21bafa1b7b
9 files changed
+103
-94
No files matched your search
@@ -156,7 +156,7 @@ for (const leaderboardChunk of chunk(leaderboard, 100)) {
|
|||||||
hits: stat.statistics.rating!.hits,
|
hits: stat.statistics.rating!.hits,
|
||||||
kills: stat.statistics.rating!.frags,
|
kills: stat.statistics.rating!.frags,
|
||||||
shots: stat.statistics.rating!.shots,
|
shots: stat.statistics.rating!.shots,
|
||||||
survived: stat.statistics.rating!.win_and_survived,
|
survived: stat.statistics.rating!.survived_battles,
|
||||||
wins: stat.statistics.rating!.wins,
|
wins: stat.statistics.rating!.wins,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ export interface ClanStats {
|
|||||||
dropped_capture_points: number;
|
dropped_capture_points: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface RatingStats {
|
export interface RatingStats {
|
||||||
spotted: number;
|
spotted: number;
|
||||||
calibration_battles_left: number;
|
calibration_battles_left: number;
|
||||||
hits: number;
|
hits: number;
|
||||||
|
|||||||
@@ -1,7 +1,9 @@
|
|||||||
import { RatingsInfo } from '../../commands/ratings';
|
import { RatingsInfo } from '../../commands/ratings';
|
||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
|
import { asset } from './asset';
|
||||||
|
import { superDecompress } from './superDecompress';
|
||||||
|
|
||||||
const INFO_CACHE: Record<
|
const cache: Record<
|
||||||
Region,
|
Region,
|
||||||
Record<
|
Record<
|
||||||
number,
|
number,
|
||||||
@@ -19,18 +21,18 @@ export default async function getArchivedRatingsInfo(
|
|||||||
region: Region,
|
region: Region,
|
||||||
season: number,
|
season: number,
|
||||||
) {
|
) {
|
||||||
if (INFO_CACHE[region][season]) {
|
if (!cache[region][season]) {
|
||||||
return INFO_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(
|
return cache[region][season];
|
||||||
`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;
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
|
|
||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
|
import { BkrlDiscriminatedEntries, BkrlReadStream } from '../streams/bkrl';
|
||||||
|
import { asset } from './asset';
|
||||||
|
|
||||||
const LEADERBOARD_CACHE: Record<
|
const cache: Record<Region, Record<number, BkrlDiscriminatedEntries>> = {
|
||||||
Region,
|
|
||||||
Record<number, BlitzkriegRatingsLeaderboard>
|
|
||||||
> = {
|
|
||||||
asia: {},
|
asia: {},
|
||||||
eu: {},
|
eu: {},
|
||||||
com: {},
|
com: {},
|
||||||
@@ -14,15 +12,14 @@ export async function getArchivedRatingsLeaderboard(
|
|||||||
region: Region,
|
region: Region,
|
||||||
season: number,
|
season: number,
|
||||||
) {
|
) {
|
||||||
if (LEADERBOARD_CACHE[region][season]) {
|
if (!cache[region][season]) {
|
||||||
return LEADERBOARD_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(
|
return cache[region][season];
|
||||||
`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;
|
|
||||||
}
|
}
|
||||||
@@ -1,10 +1,8 @@
|
|||||||
import { BlitzkriegRatingsLeaderboard } from '../../../scripts/buildRatingsLeaderboard';
|
|
||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
|
import { BkrlDiscriminatedEntries, BkrlReadStream } from '../streams/bkrl';
|
||||||
|
import { asset } from './asset';
|
||||||
|
|
||||||
const MIDNIGHT_LEADERBOARD_CACHE: Record<
|
const cache: Record<Region, Record<number, BkrlDiscriminatedEntries | null>> = {
|
||||||
Region,
|
|
||||||
Record<number, BlitzkriegRatingsLeaderboard>
|
|
||||||
> = {
|
|
||||||
com: {},
|
com: {},
|
||||||
eu: {},
|
eu: {},
|
||||||
asia: {},
|
asia: {},
|
||||||
@@ -14,21 +12,18 @@ export default async function getArchivedRatingsMidnightLeaderboard(
|
|||||||
region: Region,
|
region: Region,
|
||||||
season: number,
|
season: number,
|
||||||
) {
|
) {
|
||||||
if (MIDNIGHT_LEADERBOARD_CACHE[region][season]) {
|
if (!cache[region][season]) {
|
||||||
return MIDNIGHT_LEADERBOARD_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 {
|
return cache[region][season];
|
||||||
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}`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -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>;
|
||||||
|
}
|
||||||
@@ -5,60 +5,55 @@ import {
|
|||||||
} from '../../types/tanksStats';
|
} from '../../types/tanksStats';
|
||||||
|
|
||||||
export function deltaTankStats(
|
export function deltaTankStats(
|
||||||
a: NormalizedTankStats,
|
aRaw: NormalizedTankStats,
|
||||||
b: NormalizedTankStats,
|
bRaw: NormalizedTankStats,
|
||||||
time?: number,
|
time?: number,
|
||||||
) {
|
) {
|
||||||
const bTanks = Object.keys(b);
|
const bTanks = Object.keys(bRaw);
|
||||||
const changedTanks = bTanks.filter((id) => {
|
const changedTanks = bTanks.filter((id) => {
|
||||||
return (
|
return (
|
||||||
a[id as unknown as number]?.all.battles !==
|
aRaw[id as unknown as number]?.all.battles !==
|
||||||
b[id as unknown as number].all.battles &&
|
bRaw[id as unknown as number].all.battles &&
|
||||||
(time === undefined
|
(time === undefined
|
||||||
? true
|
? 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 diff = changedTanks.map((id) => {
|
||||||
const aTank = a[id as unknown as number] ?? emptyIndividualTankStats;
|
const a = aRaw[id as unknown as number] ?? emptyIndividualTankStats;
|
||||||
const bTank = b[id as unknown as number];
|
const b = bRaw[id as unknown as number];
|
||||||
|
|
||||||
const tankDiff = {
|
const tankDiff = {
|
||||||
account_id: bTank.account_id,
|
account_id: b.account_id,
|
||||||
battle_life_time: bTank.battle_life_time,
|
battle_life_time: b.battle_life_time,
|
||||||
frags: (bTank.frags ?? aTank.frags ?? 0) - (aTank.frags ?? 0),
|
frags: (b.frags ?? a.frags ?? 0) - (a.frags ?? 0),
|
||||||
max_frags: Math.max(aTank.max_frags, bTank.max_frags),
|
max_frags: Math.max(a.max_frags, b.max_frags),
|
||||||
in_garage: bTank.in_garage,
|
in_garage: b.in_garage,
|
||||||
max_xp: Math.max(aTank.max_xp, bTank.max_xp),
|
max_xp: Math.max(a.max_xp, b.max_xp),
|
||||||
in_garage_updated: bTank.in_garage_updated,
|
in_garage_updated: b.in_garage_updated,
|
||||||
last_battle_time: Math.max(
|
last_battle_time: Math.max(b.last_battle_time, a.last_battle_time),
|
||||||
bTank.last_battle_time,
|
mark_of_mastery: b.mark_of_mastery,
|
||||||
aTank.last_battle_time,
|
tank_id: b.tank_id,
|
||||||
),
|
|
||||||
mark_of_mastery: bTank.mark_of_mastery,
|
|
||||||
tank_id: bTank.tank_id,
|
|
||||||
|
|
||||||
all: {
|
all: {
|
||||||
battles: bTank.all.battles - aTank.all.battles,
|
battles: b.all.battles - a.all.battles,
|
||||||
wins: bTank.all.wins - aTank.all.wins,
|
wins: b.all.wins - a.all.wins,
|
||||||
capture_points: bTank.all.capture_points - aTank.all.capture_points,
|
capture_points: b.all.capture_points - a.all.capture_points,
|
||||||
damage_dealt: bTank.all.damage_dealt - aTank.all.damage_dealt,
|
damage_dealt: b.all.damage_dealt - a.all.damage_dealt,
|
||||||
damage_received: bTank.all.damage_received - aTank.all.damage_received,
|
damage_received: b.all.damage_received - a.all.damage_received,
|
||||||
dropped_capture_points:
|
dropped_capture_points:
|
||||||
bTank.all.dropped_capture_points - aTank.all.dropped_capture_points,
|
b.all.dropped_capture_points - a.all.dropped_capture_points,
|
||||||
frags: bTank.all.frags - aTank.all.frags,
|
frags: b.all.frags - a.all.frags,
|
||||||
frags8p: bTank.all.frags8p - aTank.all.frags8p,
|
frags8p: b.all.frags8p - a.all.frags8p,
|
||||||
hits: bTank.all.hits - aTank.all.hits,
|
hits: b.all.hits - a.all.hits,
|
||||||
losses: bTank.all.losses - aTank.all.losses,
|
losses: b.all.losses - a.all.losses,
|
||||||
max_frags: Math.max(aTank.max_frags, bTank.max_frags),
|
max_frags: Math.max(a.max_frags, b.max_frags),
|
||||||
max_xp: Math.max(aTank.max_xp, bTank.max_xp),
|
max_xp: Math.max(a.max_xp, b.max_xp),
|
||||||
shots: bTank.all.shots - aTank.all.shots,
|
shots: b.all.shots - a.all.shots,
|
||||||
spotted: bTank.all.spotted - aTank.all.spotted,
|
spotted: b.all.spotted - a.all.spotted,
|
||||||
survived_battles:
|
survived_battles: b.all.survived_battles - a.all.survived_battles,
|
||||||
bTank.all.survived_battles - aTank.all.survived_battles,
|
win_and_survived: b.all.win_and_survived - a.all.win_and_survived,
|
||||||
win_and_survived:
|
xp: b.all.xp - a.all.xp,
|
||||||
bTank.all.win_and_survived - aTank.all.win_and_survived,
|
|
||||||
xp: bTank.all.xp - aTank.all.xp,
|
|
||||||
},
|
},
|
||||||
} satisfies IndividualTankStats;
|
} satisfies IndividualTankStats;
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export interface BkrlComprehensive1Entry {
|
|||||||
kills: number;
|
kills: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
type DiscriminatedEntries =
|
export type BkrlDiscriminatedEntries =
|
||||||
| {
|
| {
|
||||||
format: BkrlFormat.Minimal;
|
format: BkrlFormat.Minimal;
|
||||||
entries: BkrlMinimalEntry[];
|
entries: BkrlMinimalEntry[];
|
||||||
@@ -45,7 +45,7 @@ export class BkrlReadStream extends ReadStream {
|
|||||||
return this.body(header);
|
return this.body(header);
|
||||||
}
|
}
|
||||||
|
|
||||||
body(header: ReturnType<typeof this.header>): DiscriminatedEntries {
|
body(header: ReturnType<typeof this.header>): BkrlDiscriminatedEntries {
|
||||||
switch (header.format) {
|
switch (header.format) {
|
||||||
case BkrlFormat.Minimal: {
|
case BkrlFormat.Minimal: {
|
||||||
return {
|
return {
|
||||||
@@ -107,13 +107,13 @@ export class BkrlReadStream extends ReadStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export class BkrlWriteStream extends WriteStream {
|
export class BkrlWriteStream extends WriteStream {
|
||||||
bkrl(discriminatedEntries: DiscriminatedEntries) {
|
bkrl(discriminatedEntries: BkrlDiscriminatedEntries) {
|
||||||
this.magic();
|
this.magic();
|
||||||
this.header(discriminatedEntries);
|
this.header(discriminatedEntries);
|
||||||
this.body(discriminatedEntries);
|
this.body(discriminatedEntries);
|
||||||
}
|
}
|
||||||
|
|
||||||
body(discriminatedEntries: DiscriminatedEntries) {
|
body(discriminatedEntries: BkrlDiscriminatedEntries) {
|
||||||
switch (discriminatedEntries.format) {
|
switch (discriminatedEntries.format) {
|
||||||
case BkrlFormat.Minimal: {
|
case BkrlFormat.Minimal: {
|
||||||
discriminatedEntries.entries.forEach((entry) => {
|
discriminatedEntries.entries.forEach((entry) => {
|
||||||
@@ -145,7 +145,7 @@ export class BkrlWriteStream extends WriteStream {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
header(discriminatedEntries: DiscriminatedEntries) {
|
header(discriminatedEntries: BkrlDiscriminatedEntries) {
|
||||||
this.uint16(1);
|
this.uint16(1);
|
||||||
this.uint8(discriminatedEntries.format);
|
this.uint8(discriminatedEntries.format);
|
||||||
this.uint32(discriminatedEntries.entries.length);
|
this.uint32(discriminatedEntries.entries.length);
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import { researchCommand } from '../../commands/research';
|
|||||||
import { searchClansCommand } from '../../commands/searchClans';
|
import { searchClansCommand } from '../../commands/searchClans';
|
||||||
import { searchPlayersCommand } from '../../commands/searchPlayers';
|
import { searchPlayersCommand } from '../../commands/searchPlayers';
|
||||||
import { statsCommand } from '../../commands/stats';
|
import { statsCommand } from '../../commands/stats';
|
||||||
|
import { testCommand } from '../../commands/test';
|
||||||
import { todayCommand } from '../../commands/today';
|
import { todayCommand } from '../../commands/today';
|
||||||
import getClientId from '../../core/blitzkrieg/getClientId';
|
import getClientId from '../../core/blitzkrieg/getClientId';
|
||||||
import isDev from '../../core/blitzkrieg/isDev';
|
import isDev from '../../core/blitzkrieg/isDev';
|
||||||
@@ -95,6 +96,7 @@ export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
|
|||||||
ratingsCommand,
|
ratingsCommand,
|
||||||
todayCommand,
|
todayCommand,
|
||||||
researchCommand,
|
researchCommand,
|
||||||
|
testCommand,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const commands = Promise.allSettled(COMMANDS_RAW).then((rawCommands) => {
|
export const commands = Promise.allSettled(COMMANDS_RAW).then((rawCommands) => {
|
||||||
|
|||||||
Reference in new issue
Block a user