From 4b5e0d1c1cd3826c82dc75e90cdd95f807826b3a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 16 Nov 2023 10:58:19 -0600 Subject: [PATCH 1/7] feat: american neighbor spelling --- src/commands/ratings.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/commands/ratings.tsx b/src/commands/ratings.tsx index 7abe31c82..347e752b2 100644 --- a/src/commands/ratings.tsx +++ b/src/commands/ratings.tsx @@ -123,14 +123,14 @@ function addSubcommands( .addSubcommand((option) => addOptions( option - .setName('neighbours') - .setDescription('Your position and neighbours'), + .setName('neighbors') + .setDescription('Your position and neighbors'), ) .addStringOption(addUsernameChoices) .addIntegerOption((option) => option .setName('limit') - .setDescription('How many neighbours to display (default: 10)') + .setDescription('How many neighbors to display (default: 10)') .setRequired(false) .setMinValue(5) .setMaxValue(30), @@ -228,7 +228,7 @@ export const ratingsCommand = new Promise( | 'current'; const subcommand = interaction.options.getSubcommand(true) as | 'league' - | 'neighbours'; + | 'neighbors'; const limit = interaction.options.getInteger('limit') ?? 10; const seasonOption = interaction.options.getString('season'); const season = seasonOption ? parseInt(seasonOption) : undefined; @@ -414,7 +414,7 @@ export const ratingsCommand = new Promise( titleName = neighbors ? accountInfo.nickname : `No Ongoing Season - ${REGION_NAMES_SHORT[region]}`; - titleDescription = 'Ratings neighbours'; + titleDescription = 'Ratings neighbors'; playersBefore = neighbors ? neighbors[0].position - 1 : 0; playersAfter = regionRatingsInfo.count - neighbors[neighbors.length - 1].position; From 14710b52180052531bd1eaf365831d56a986fdea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:13:51 -0600 Subject: [PATCH 2/7] fix: use non-caching apis for ratings command --- src/app/tools/ratings/page.tsx | 7 ++-- src/commands/ratings.tsx | 46 ++++++++++++--------------- src/core/blitz/getRatingsLeague.ts | 13 +++++--- src/core/blitz/getRatingsNeighbors.ts | 7 ++-- 4 files changed, 35 insertions(+), 38 deletions(-) diff --git a/src/app/tools/ratings/page.tsx b/src/app/tools/ratings/page.tsx index 3d3661c09..a60b7a8ac 100644 --- a/src/app/tools/ratings/page.tsx +++ b/src/app/tools/ratings/page.tsx @@ -137,15 +137,12 @@ export default function Page() { await Promise.all( range(0, 5).map(async (league: number) => { const data = await getRatingsLeague(region, league); - leaguePositionCache.current[region][league] = - data.result[0].number - 1; + leaguePositionCache.current[region][league] = data[0].number - 1; return data; }), ) - ) - .map(({ result }) => result) - .flat(); + ).flat(); useLeaderboardCache.setState( produce((draft: LeaderboardCache) => { diff --git a/src/commands/ratings.tsx b/src/commands/ratings.tsx index 347e752b2..d1067e78a 100644 --- a/src/commands/ratings.tsx +++ b/src/commands/ratings.tsx @@ -15,6 +15,8 @@ import { REGION_NAMES_SHORT, Region } from '../constants/regions'; import { getAccountInfo } from '../core/blitz/getAccountInfo'; import { getClanAccountInfo } from '../core/blitz/getClanAccountInfo'; import getRatingsInfo from '../core/blitz/getRatingsInfo'; +import { getRatingsLeague } from '../core/blitz/getRatingsLeague'; +import { getRatingsNeighbors } from '../core/blitz/getRatingsNeighbors'; import regionToRegionSubdomain from '../core/blitz/regionToRegionSubdomain'; import { getArchivedLatestSeasonNumber } from '../core/blitzkrieg/getArchivedLatestSeasonNumber'; import getArchivedRatingsInfo from '../core/blitzkrieg/getArchivedRatingsInfo'; @@ -257,11 +259,8 @@ export const ratingsCommand = new Promise( const regionSubdomain = regionToRegionSubdomain(region); const result = subcommandGroup === 'current' - ? await fetch( - `https://${regionSubdomain}.wotblitz.com/en/api/rating-leaderboards/league/${leagueIndex}/top/`, - ) - .then((response) => response.json() as Promise) - .then(async ({ result }) => + ? await getRatingsLeague(region, leagueIndex).then( + async (result) => result.slice(0, limit).map( (player) => ({ @@ -272,7 +271,7 @@ export const ratingsCommand = new Promise( nickname: player.nickname, }) satisfies SimplifiedPlayer, ), - ) + ) : await getArchivedRatingsLeaderboard(region, season!).then( async (players) => { const firstPlayerIndex = @@ -338,29 +337,24 @@ export const ratingsCommand = new Promise( const accountInfo = await getAccountInfo(region, id); const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan; - const regionSubdomain = regionToRegionSubdomain(region); const neighbors = subcommandGroup === 'current' - ? await fetch( - `https://${regionSubdomain}.wotblitz.com/en/api/rating-leaderboards/user/${id}/?neighbors=${Math.round( - limit / 2, - )}`, + ? await getRatingsNeighbors( + region, + id, + Math.round(limit / 2), + ).then((players) => + players.neighbors.map( + (player) => + ({ + id: player.spa_id, + position: player.number, + score: player.score, + clan: player.clan_tag, + nickname: player.nickname, + }) satisfies SimplifiedPlayer, + ), ) - .then( - (response) => response.json() as Promise, - ) - .then((players) => - players.neighbors.map( - (player) => - ({ - id: player.spa_id, - position: player.number, - score: player.score, - clan: player.clan_tag, - nickname: player.nickname, - }) satisfies SimplifiedPlayer, - ), - ) : await getArchivedRatingsLeaderboard(region, season!).then( async (players) => { const playerIndex = players.findIndex( diff --git a/src/core/blitz/getRatingsLeague.ts b/src/core/blitz/getRatingsLeague.ts index 49445335e..6779cc78b 100644 --- a/src/core/blitz/getRatingsLeague.ts +++ b/src/core/blitz/getRatingsLeague.ts @@ -1,4 +1,4 @@ -import { LeagueTop } from '../../commands/ratings'; +import { LeagueTop, RatingsPlayer } from '../../commands/ratings'; import { Region } from '../../constants/regions'; import { context } from '../blitzkrieg/context'; import { patientFetch } from '../blitzkrieg/patientFetch'; @@ -9,7 +9,10 @@ export async function getRatingsLeague( league: number, usePatientFetcher = false, ) { - const fetcher = usePatientFetcher ? patientFetch : fetch; + const fetcher = (url: string) => + usePatientFetcher + ? patientFetch(url, undefined, { cache: 'no-store' }) + : fetch(url, { cache: 'no-store' }); const response = await fetcher( context === 'website' ? `/api/${region}/ratings/current/league/${league}` @@ -17,7 +20,9 @@ export async function getRatingsLeague( region, )}.wotblitz.com/en/api/rating-leaderboards/league/${league}/top/`, ); - const json = (await response.json()) as LeagueTop; + const json = await response.json(); - return json; + return context === 'website' + ? (json as RatingsPlayer[]) + : (json as LeagueTop).result; } diff --git a/src/core/blitz/getRatingsNeighbors.ts b/src/core/blitz/getRatingsNeighbors.ts index 045cf9a01..2cd33aab9 100644 --- a/src/core/blitz/getRatingsNeighbors.ts +++ b/src/core/blitz/getRatingsNeighbors.ts @@ -10,9 +10,10 @@ export async function getRatingsNeighbors( count: number, usePatientFetcher = false, ) { - const fetcher = usePatientFetcher - ? patientFetch - : (url: string) => fetch(url, { cache: 'no-store' }); + const fetcher = (url: string) => + usePatientFetcher + ? patientFetch(url, undefined, { cache: 'no-store' }) + : fetch(url, { cache: 'no-store' }); const response = await fetcher( withCORSProxy( `https://${regionToRegionSubdomain( From ee6d2e7d82323a3a6915880276c8489aefaac5f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:14:38 -0600 Subject: [PATCH 3/7] feat: remove neighbor relative positional caching --- src/app/tools/ratings/page.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/app/tools/ratings/page.tsx b/src/app/tools/ratings/page.tsx index a60b7a8ac..fe70ff97f 100644 --- a/src/app/tools/ratings/page.tsx +++ b/src/app/tools/ratings/page.tsx @@ -305,13 +305,14 @@ export default function Page() { if (seedingPlayerNeighborEntry === undefined) return null; - const seedingPlayerPosition = parseInt(seedingPlayerNeighborEntry[0]); + // const seedingPlayerPosition = parseInt(seedingPlayerNeighborEntry[0]); const { neighbors } = await getRatingsNeighbors(region, id, size, true); useLeaderboardCache.setState( produce((draft: LeaderboardCache) => { neighbors.forEach((neighbor, neighborIndex) => { - const position = neighborIndex - radius + seedingPlayerPosition; + // const position = neighborIndex - radius + seedingPlayerPosition; + const position = neighbor.number - 1; if (!(position in draft[region][season])) { draft[region][season][position] = neighbor.spa_id; From e0a719ee93c7f932f760e429a3d3997dbf781aab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:41:52 -0600 Subject: [PATCH 4/7] fix: patient JSON parsing --- .vscode/settings.json | 1 + scripts/buildRatingsLeaderboard.ts | 21 ++++++++------------- src/core/blitzkrieg/patientFetchJSON.ts | 23 +++++++++++++++++++++++ 3 files changed, 32 insertions(+), 13 deletions(-) create mode 100644 src/core/blitzkrieg/patientFetchJSON.ts diff --git a/.vscode/settings.json b/.vscode/settings.json index b89dc3f62..543f4b3be 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -13,6 +13,7 @@ "Everytime", "fullstats", "fuzzysort", + "immer", "kranvagn", "Leaderboard", "leaderboards", diff --git a/scripts/buildRatingsLeaderboard.ts b/scripts/buildRatingsLeaderboard.ts index a2b2fe43f..564bffb66 100644 --- a/scripts/buildRatingsLeaderboard.ts +++ b/scripts/buildRatingsLeaderboard.ts @@ -6,7 +6,7 @@ import { RatingsNeighbors, RatingsPlayer, } from '../src/commands/ratings'; -import { patientFetch } from '../src/core/blitzkrieg/patientFetch'; +import { patientFetchJSON } from '../src/core/blitzkrieg/patientFetchJSON'; import commitMultipleFiles from './commitMultipleFiles.js'; /* @@ -29,11 +29,9 @@ const server = argv.find((arg) => arg.startsWith('--region='))?.split('=')[1]; if (!server) throw new Error('Region parameter not specified'); const NEIGHBORS = 1024; -const PLAYERS = await patientFetch( +const PLAYERS = await patientFetchJSON( `https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`, -) - .then((response) => response.json() as Promise) - .then((data) => (data.detail === undefined ? data.count : undefined)); +).then((data) => (data.detail === undefined ? data.count : undefined)); if (PLAYERS === undefined) { throw new Error('No current ratings season running'); @@ -44,9 +42,9 @@ const leaderboard: BlitzkriegRatingsLeaderboard = []; let registered = 0; async function branchFromPlayer(id: number) { - const { neighbors } = await patientFetch( + const { neighbors } = await patientFetchJSON( `https://${server}.wotblitz.com/en/api/rating-leaderboards/user/${id}/?neighbors=${NEIGHBORS}`, - ).then((response) => response.json() as Promise); + ); const firstPlayer = neighbors[0]; const lastPlayer = neighbors[neighbors.length - 1]; @@ -75,9 +73,9 @@ async function branchFromPlayer(id: number) { } async function branchFromLeague(id: number) { - const { result } = await patientFetch( + const { result } = await patientFetchJSON<{ result: RatingsPlayer[] }>( `https://${server}.wotblitz.com/en/api/rating-leaderboards/league/${id}/top/`, - ).then((response) => response.json() as Promise<{ result: RatingsPlayer[] }>); + ); const firstPlayer = result[0]; const lastPlayer = result[result.length - 1]; @@ -113,11 +111,8 @@ const leaderboardJSON = JSON.stringify(leaderboard); if (publish) { const octokit = new Octokit({ auth: env.GH_TOKEN }); - const info = await patientFetch( + const info = await patientFetchJSON( `https://${server}.wotblitz.com/en/api/rating-leaderboards/season/`, - ).then( - (response) => - response.json() as Promise, ); const normalizedServer = server === 'na' ? 'com' : server; diff --git a/src/core/blitzkrieg/patientFetchJSON.ts b/src/core/blitzkrieg/patientFetchJSON.ts new file mode 100644 index 000000000..c96b4dc83 --- /dev/null +++ b/src/core/blitzkrieg/patientFetchJSON.ts @@ -0,0 +1,23 @@ +export async function patientFetchJSON( + url: string, + timeout = 1000, + options?: Partial<{ cache: 'no-store' }>, +) { + let patientJSON: Type; + + while (patientJSON! === undefined) { + try { + patientJSON = (await fetch(url, options).then(({ json }) => + json(), + )) as Type; + } catch (error) { + console.warn( + `Failed to fetch ${url} as JSON; retrying in ${timeout}ms...`, + error, + ); + await new Promise((resolve) => setTimeout(resolve, timeout)); + } + } + + return patientJSON; +} From c7207799e21b676e1d9480eab7e3f4a0b5892e14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:45:44 -0600 Subject: [PATCH 5/7] feat: changelogs --- .vscode/settings.json | 1 + docs/changelogs/1.15.1.md | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 docs/changelogs/1.15.1.md diff --git a/.vscode/settings.json b/.vscode/settings.json index 543f4b3be..45f0cf251 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,6 +17,7 @@ "kranvagn", "Leaderboard", "leaderboards", + "MURICA", "Oopsy", "outdir", "outfile", diff --git a/docs/changelogs/1.15.1.md b/docs/changelogs/1.15.1.md new file mode 100644 index 000000000..8522c2f30 --- /dev/null +++ b/docs/changelogs/1.15.1.md @@ -0,0 +1,19 @@ +# Blitzkrieg 1.15.0 + +'MURICA! + +## Changes + +- "Neighbor" is now spelled in the American way + +## Technical features + +- Added capability to fetch patiently while also parsing the JSON + +## Technical changes + +- Removed neighbor relative position caching + +## Technical fixes + +- `/ratings` now uses the non-caching APIs From 81c1a50052853214f05fbcd98c8946cd717de9fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:47:32 -0600 Subject: [PATCH 6/7] fix: guide link --- docs/.vitepress/config.ts | 2 +- docs/changelogs/1.15.1.md | 4 ++++ docs/index.md | 4 ++-- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 3a60f46c9..08880bb3e 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -13,7 +13,7 @@ export default defineConfig({ themeConfig: { nav: [ { text: 'Home', link: '/' }, - { text: 'Guide', link: '/guide/about' }, + { text: 'Guide', link: '/guide/introduction' }, ], sidebar: [ diff --git a/docs/changelogs/1.15.1.md b/docs/changelogs/1.15.1.md index 8522c2f30..6a0d35c5e 100644 --- a/docs/changelogs/1.15.1.md +++ b/docs/changelogs/1.15.1.md @@ -6,6 +6,10 @@ - "Neighbor" is now spelled in the American way +## Fixes + +- Fixed the guide link on the documentation website + ## Technical features - Added capability to fetch patiently while also parsing the JSON diff --git a/docs/index.md b/docs/index.md index bcb10e1f0..f0b1cc7e1 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,10 +12,10 @@ hero: actions: - theme: brand text: Add to Discord Server - link: guide/install + link: /guide/install - theme: alt text: Guide - link: /guide/about + link: /guide/introduction features: - title: Clean and Efficient UI From 82f03583fe9fd1a2a3855894c08690704769f12f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Thu, 16 Nov 2023 11:51:10 -0600 Subject: [PATCH 7/7] feat: updated docs with latest info --- docs/changelogs/1.15.1.md | 1 + docs/guide/install.md | 17 ----------------- docs/guide/introduction.md | 14 +++++++++++++- docs/index.md | 2 +- 4 files changed, 15 insertions(+), 19 deletions(-) delete mode 100644 docs/guide/install.md diff --git a/docs/changelogs/1.15.1.md b/docs/changelogs/1.15.1.md index 6a0d35c5e..15772a353 100644 --- a/docs/changelogs/1.15.1.md +++ b/docs/changelogs/1.15.1.md @@ -5,6 +5,7 @@ ## Changes - "Neighbor" is now spelled in the American way +- Updated documentation website with the latest information ## Fixes diff --git a/docs/guide/install.md b/docs/guide/install.md deleted file mode 100644 index 91e0a3ec2..000000000 --- a/docs/guide/install.md +++ /dev/null @@ -1,17 +0,0 @@ -# Installing Blitzkrieg - -It's easy as 1, 2, 3! - -## Step 1 - -Join a server that already has Blitzkrieg or [join our official Discord server](https://discord.gg/nDt7AjGJQH). - -## Step 2 - -View the bot's profile and click "Add to Server". - - - -## Step 3 - -Review the permissions the bot is asking for and add it to your server! diff --git a/docs/guide/introduction.md b/docs/guide/introduction.md index 80e2f87a3..733ba8c6b 100644 --- a/docs/guide/introduction.md +++ b/docs/guide/introduction.md @@ -1,6 +1,10 @@ # Introduction -Blitzkrieg is a multipurpose bot for anything and everything World of Tanks Blitz. +🎉 Services for everything and anything World of Tanks Blitz + +## Bot + +Blitzkrieg is available as a Discord bot and can be [installed very easily](/guide/invite). - Track statistics - Find inactive players in a clan @@ -8,3 +12,11 @@ Blitzkrieg is a multipurpose bot for anything and everything World of Tanks Blit - Create embeds for streams - Track a player/tanks statistical evolution - ...and a variety of other similar things + +## Website + +Provides a bunch of very helpful tools; https://blitz-krieg.vercel.app/ + +- Session tracker +- Ratings leaderboard +- Way more to come diff --git a/docs/index.md b/docs/index.md index f0b1cc7e1..22e3f283d 100644 --- a/docs/index.md +++ b/docs/index.md @@ -12,7 +12,7 @@ hero: actions: - theme: brand text: Add to Discord Server - link: /guide/install + link: /guide/invite - theme: alt text: Guide link: /guide/introduction