2023-07-14 01:32:20 +00:00
|
|
|
import { Octokit } from '@octokit/rest';
|
|
|
|
|
import { rm, writeFile } from 'fs/promises';
|
|
|
|
|
import { argv, env } from 'process';
|
2023-07-16 17:51:01 +00:00
|
|
|
import {
|
|
|
|
|
RatingsInfo,
|
|
|
|
|
RatingsNeighbors,
|
|
|
|
|
RatingsPlayer,
|
|
|
|
|
} from '../src/commands/ratings';
|
2023-11-16 11:41:52 -06:00
|
|
|
import { patientFetchJSON } from '../src/core/blitzkrieg/patientFetchJSON';
|
2023-07-14 01:32:20 +00:00
|
|
|
import commitMultipleFiles from './commitMultipleFiles.js';
|
|
|
|
|
|
2023-07-14 01:52:05 +00:00
|
|
|
/*
|
2023-07-14 17:27:57 +00:00
|
|
|
* Central North American Time (UTC-5): use 0 5 * * *.
|
|
|
|
|
* Central European Time (UTC+1): use 0 23 * * *.
|
|
|
|
|
* Central Asia Standard Time (UTC+7): use 0 17 * * *.
|
|
|
|
|
*
|
2023-10-31 12:41:27 -05:00
|
|
|
* [region]/ratings/[season]/info.json: season info like rewards, start & end time, etc.
|
|
|
|
|
* [region]/ratings/[season]/latest.json: the absolute latest leaderboard recorded at UTC+0 midnight
|
|
|
|
|
* [region]/ratings/[season]/midnight.json: last midnight's leaderboard relative to the region
|
2023-07-14 17:27:57 +00:00
|
|
|
*/
|
2023-07-14 01:52:05 +00:00
|
|
|
|
2023-11-07 18:58:19 -06:00
|
|
|
export type BlitzkriegRatingsLeaderboardEntry = { id: number; score: number };
|
|
|
|
|
export type BlitzkriegRatingsLeaderboard = BlitzkriegRatingsLeaderboardEntry[];
|
2023-07-16 17:56:37 +00:00
|
|
|
|
2023-07-14 01:32:20 +00:00
|
|
|
const publish = argv.includes('--publish');
|
2023-07-14 17:27:57 +00:00
|
|
|
const latest = argv.includes('--latest');
|
2023-07-14 01:52:05 +00:00
|
|
|
const server = argv.find((arg) => arg.startsWith('--region='))?.split('=')[1];
|
|
|
|
|
|
|
|
|
|
if (!server) throw new Error('Region parameter not specified');
|
2023-07-14 01:32:20 +00:00
|
|
|
|
2023-11-20 13:32:53 -06:00
|
|
|
const NEIGHBORS = 2 ** 8;
|
2023-11-16 11:41:52 -06:00
|
|
|
const PLAYERS = await patientFetchJSON<RatingsInfo>(
|
2023-07-14 01:32:20 +00:00
|
|
|
`https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`,
|
2023-11-16 11:41:52 -06:00
|
|
|
).then((data) => (data.detail === undefined ? data.count : undefined));
|
2023-09-07 01:13:03 +00:00
|
|
|
|
|
|
|
|
if (PLAYERS === undefined) {
|
|
|
|
|
throw new Error('No current ratings season running');
|
|
|
|
|
}
|
2023-07-14 01:32:20 +00:00
|
|
|
|
2023-07-15 01:21:59 +00:00
|
|
|
const players: Record<number, RatingsPlayer> = {};
|
2023-07-16 17:56:37 +00:00
|
|
|
const leaderboard: BlitzkriegRatingsLeaderboard = [];
|
2023-07-14 01:32:20 +00:00
|
|
|
let registered = 0;
|
|
|
|
|
|
2023-07-15 01:21:59 +00:00
|
|
|
async function branchFromPlayer(id: number) {
|
2023-11-16 11:41:52 -06:00
|
|
|
const { neighbors } = await patientFetchJSON<RatingsNeighbors>(
|
2023-07-14 01:32:20 +00:00
|
|
|
`https://${server}.wotblitz.com/en/api/rating-leaderboards/user/${id}/?neighbors=${NEIGHBORS}`,
|
2023-11-16 11:41:52 -06:00
|
|
|
);
|
2023-07-14 01:32:20 +00:00
|
|
|
|
|
|
|
|
const firstPlayer = neighbors[0];
|
|
|
|
|
const lastPlayer = neighbors[neighbors.length - 1];
|
|
|
|
|
|
2023-07-15 01:21:59 +00:00
|
|
|
const branches: Promise<void>[] = [];
|
2023-07-14 01:32:20 +00:00
|
|
|
if (!players[firstPlayer.number])
|
|
|
|
|
branches.push(branchFromPlayer(firstPlayer.spa_id));
|
|
|
|
|
if (!players[lastPlayer.number])
|
|
|
|
|
branches.push(branchFromPlayer(lastPlayer.spa_id));
|
|
|
|
|
|
|
|
|
|
neighbors.forEach((neighbor) => {
|
|
|
|
|
if (players[neighbor.number]) return;
|
|
|
|
|
|
|
|
|
|
players[neighbor.number] = neighbor;
|
|
|
|
|
registered++;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
console.log(
|
|
|
|
|
`Registered ${registered} / ${PLAYERS} (${(
|
2023-09-07 01:13:03 +00:00
|
|
|
(registered / PLAYERS!) *
|
2023-07-14 01:32:20 +00:00
|
|
|
100
|
|
|
|
|
).toFixed(2)}%)`,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
await Promise.all(branches);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-15 01:21:59 +00:00
|
|
|
async function branchFromLeague(id: number) {
|
2023-11-16 11:41:52 -06:00
|
|
|
const { result } = await patientFetchJSON<{ result: RatingsPlayer[] }>(
|
2023-07-14 01:32:20 +00:00
|
|
|
`https://${server}.wotblitz.com/en/api/rating-leaderboards/league/${id}/top/`,
|
2023-11-16 11:41:52 -06:00
|
|
|
);
|
2023-07-14 01:32:20 +00:00
|
|
|
|
|
|
|
|
const firstPlayer = result[0];
|
|
|
|
|
const lastPlayer = result[result.length - 1];
|
|
|
|
|
|
|
|
|
|
await Promise.all([
|
|
|
|
|
branchFromPlayer(firstPlayer.spa_id),
|
|
|
|
|
branchFromPlayer(lastPlayer.spa_id),
|
|
|
|
|
]);
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-15 01:21:59 +00:00
|
|
|
console.log('Branching from leagues...');
|
2023-07-14 01:32:20 +00:00
|
|
|
await Promise.all([
|
|
|
|
|
branchFromLeague(0),
|
|
|
|
|
branchFromLeague(1),
|
|
|
|
|
branchFromLeague(2),
|
|
|
|
|
branchFromLeague(3),
|
|
|
|
|
branchFromLeague(4),
|
|
|
|
|
]);
|
|
|
|
|
|
|
|
|
|
console.log('Converting to an array...');
|
|
|
|
|
for (let index = 0; index < PLAYERS; index++) {
|
2023-07-16 17:56:37 +00:00
|
|
|
const listing = players[index + 1];
|
|
|
|
|
if (!listing) console.warn(`Position ${index + 1} had no player`);
|
|
|
|
|
|
|
|
|
|
leaderboard[index] = {
|
|
|
|
|
id: listing.spa_id,
|
|
|
|
|
score: listing.score,
|
|
|
|
|
};
|
2023-07-14 01:32:20 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const leaderboardJSON = JSON.stringify(leaderboard);
|
|
|
|
|
|
|
|
|
|
if (publish) {
|
2023-07-14 01:52:05 +00:00
|
|
|
const octokit = new Octokit({ auth: env.GH_TOKEN });
|
2023-07-14 01:32:20 +00:00
|
|
|
|
2023-11-16 11:41:52 -06:00
|
|
|
const info = await patientFetchJSON<RatingsInfo & { detail: undefined }>(
|
2023-07-14 01:32:20 +00:00
|
|
|
`https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`,
|
2023-09-07 01:13:03 +00:00
|
|
|
);
|
2023-07-14 01:32:20 +00:00
|
|
|
const normalizedServer = server === 'na' ? 'com' : server;
|
|
|
|
|
|
2023-07-14 17:27:57 +00:00
|
|
|
const infoPath = `${normalizedServer}/ratings/${info.current_season}/info.json`;
|
|
|
|
|
const leaderboardPath = `${normalizedServer}/ratings/${info.current_season}/${
|
2023-07-16 17:51:01 +00:00
|
|
|
latest ? 'latest' : 'midnight'
|
|
|
|
|
}.json`;
|
2023-07-14 01:32:20 +00:00
|
|
|
const infoJSON = JSON.stringify(info);
|
|
|
|
|
|
|
|
|
|
console.log(`Publishing to season ${info.current_season}...`);
|
|
|
|
|
commitMultipleFiles(
|
|
|
|
|
octokit,
|
|
|
|
|
'tresabhi',
|
|
|
|
|
'blitzkrieg-db',
|
|
|
|
|
'main',
|
2023-07-16 17:51:01 +00:00
|
|
|
new Date().toString(),
|
2023-07-14 01:32:20 +00:00
|
|
|
[
|
|
|
|
|
{ path: infoPath, content: infoJSON },
|
|
|
|
|
{ path: leaderboardPath, content: leaderboardJSON },
|
|
|
|
|
],
|
|
|
|
|
);
|
|
|
|
|
} else {
|
|
|
|
|
console.log('Writing to disk...');
|
|
|
|
|
await rm('dist.json', { force: true });
|
|
|
|
|
await writeFile('dist.json', leaderboardJSON);
|
|
|
|
|
}
|