mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
597a1a04d2 | ||
|
|
aec6f49ea1 | ||
|
|
e1ad710de5 | ||
|
|
edc8447617 | ||
|
|
f726d4f8e8 | ||
|
|
1f333f6b88 | ||
|
|
9b855fca47 | ||
|
|
c5f433fdf4 | ||
|
|
fd61dae1c1 | ||
|
|
2c45f9759f | ||
|
|
0d3261f748 | ||
|
|
d38e873800 | ||
|
|
ca38914095 | ||
|
|
ee5beeea45 |
No files matched your search
@@ -1,4 +1,4 @@
|
|||||||
# Blitzkrieg 1.14.1
|
# Blitzkrieg 1.14.2
|
||||||
|
|
||||||
A late night hot fix for my homies
|
A late night hot fix for my homies
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
# Blitzkrieg 1.14.3
|
||||||
|
|
||||||
|
Pull your brush out and start polishing.
|
||||||
|
|
||||||
|
## Changes
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
- Rows in `/breakdown` are now chunked into `8` per image
|
||||||
|
- This is true unless the number of pages exceeds `10` in which case the rows are even distributed across all `10` pages
|
||||||
|
- `10` is the maximum number of images that Discord allows
|
||||||
|
- Short region names are used in username autocomplete instead of their full names
|
||||||
|
- Example: "North America" is "NA" now
|
||||||
|
|
||||||
|
## Fixes
|
||||||
|
|
||||||
|
- Removed reference to username inference in the username option description
|
||||||
|
- Removed an unnecessary type `asd` that did absolutely nothing used nowhere
|
||||||
|
|
||||||
|
## Technical changes
|
||||||
|
|
||||||
|
- Image orders are now preserved even if processed in parallel and all completed out of order
|
||||||
|
- `fetchBlitz` is now throttled to `10` requests per second
|
||||||
|
- Request overflows are managed by queueing
|
||||||
+1
-1
@@ -27,7 +27,7 @@ readdir('src/workers').then((workers) => {
|
|||||||
|
|
||||||
bundle: true,
|
bundle: true,
|
||||||
sourcemap: true,
|
sourcemap: true,
|
||||||
minifyIdentifiers: false, // cause goofy errors
|
minifyIdentifiers: false, // causes goofy errors
|
||||||
minifySyntax: true,
|
minifySyntax: true,
|
||||||
minifyWhitespace: true,
|
minifyWhitespace: true,
|
||||||
|
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import * as Breakdown from '../../../components/Breakdown';
|
import * as Breakdown from '../../../components/Breakdown';
|
||||||
import { TreeTypeEnum } from '../../../components/Tanks';
|
import { TreeTypeEnum } from '../../../components/Tanks';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from '../../../core/blitz/fetchWargaming';
|
import fetchBlitz from '../../../core/blitz/fetchBlitz';
|
||||||
import { tankAverages } from '../../../core/blitzstars/tankAverages';
|
import { tankAverages } from '../../../core/blitzstars/tankAverages';
|
||||||
import {
|
import {
|
||||||
TankopediaEntry,
|
TankopediaEntry,
|
||||||
|
|||||||
+130
-100
@@ -1,4 +1,5 @@
|
|||||||
import { SlashCommandBuilder } from 'discord.js';
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
import { chunk } from 'lodash';
|
||||||
import * as Breakdown from '../components/Breakdown';
|
import * as Breakdown from '../components/Breakdown';
|
||||||
import NoData, { NoDataType } from '../components/NoData';
|
import NoData, { NoDataType } from '../components/NoData';
|
||||||
import TitleBar from '../components/TitleBar';
|
import TitleBar from '../components/TitleBar';
|
||||||
@@ -35,6 +36,9 @@ import { StatFilters, filterStats } from '../core/statistics/filterStats';
|
|||||||
import getWN8Percentile from '../core/statistics/getWN8Percentile';
|
import getWN8Percentile from '../core/statistics/getWN8Percentile';
|
||||||
import { CommandRegistryRaw } from '../events/interactionCreate';
|
import { CommandRegistryRaw } from '../events/interactionCreate';
|
||||||
|
|
||||||
|
const ROWS_PER_PAGE = 8;
|
||||||
|
const MAX_PAGES = 10;
|
||||||
|
|
||||||
async function render(
|
async function render(
|
||||||
{ region, id }: ResolvedPlayer,
|
{ region, id }: ResolvedPlayer,
|
||||||
{ start, end, name }: ResolvedPeriod,
|
{ start, end, name }: ResolvedPeriod,
|
||||||
@@ -132,38 +136,80 @@ async function render(
|
|||||||
0,
|
0,
|
||||||
) / careerBattles;
|
) / careerBattles;
|
||||||
|
|
||||||
return (
|
const children: JSX.Element[] = [];
|
||||||
<Wrapper>
|
|
||||||
<TitleBar
|
|
||||||
name={accountInfo.nickname}
|
|
||||||
image={
|
|
||||||
clanData?.clan
|
|
||||||
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData?.clan?.emblem_set_id}.png`
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
description={`${name} • ${filterDescriptions}`}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{filteredOrder.length === 0 && (
|
if (filteredOrder.length > 0) {
|
||||||
<NoData type={NoDataType.BattlesInPeriod} />
|
children.push(
|
||||||
)}
|
<Breakdown.Row
|
||||||
{filteredOrder.length > 0 && (
|
key={id}
|
||||||
<Breakdown.Root>
|
type="summary"
|
||||||
|
title="Total"
|
||||||
|
stats={[
|
||||||
|
{
|
||||||
|
title: 'Battles',
|
||||||
|
current: currentBattles,
|
||||||
|
career: careerBattles,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Winrate',
|
||||||
|
current: `${(100 * currentWinrate).toFixed(2)}%`,
|
||||||
|
career: `${(100 * careerWinrate).toFixed(2)}%`,
|
||||||
|
delta: currentWinrate - careerWinrate,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'WN8',
|
||||||
|
current:
|
||||||
|
currentWN8 === undefined
|
||||||
|
? undefined
|
||||||
|
: Math.round(currentWN8).toLocaleString(),
|
||||||
|
career:
|
||||||
|
careerWN8 === undefined
|
||||||
|
? undefined
|
||||||
|
: Math.round(careerWN8).toLocaleString(),
|
||||||
|
percentile:
|
||||||
|
currentWN8 === undefined
|
||||||
|
? undefined
|
||||||
|
: getWN8Percentile(currentWN8),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: 'Damage',
|
||||||
|
current: Math.round(currentDamage).toLocaleString(),
|
||||||
|
career: Math.round(careerDamage).toLocaleString(),
|
||||||
|
delta: currentDamage - careerDamage,
|
||||||
|
},
|
||||||
|
]}
|
||||||
|
/>,
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
filteredOrder.map(async (id, index) => {
|
||||||
|
const tankopediaEntry = awaitedTankopedia[id];
|
||||||
|
const current = orderedCurrentStats[index];
|
||||||
|
const career = orderedCareerStats[index];
|
||||||
|
const currentWN8 = orderedCurrentWN8[index];
|
||||||
|
const careerWN8 = orderedCareerWN8[index];
|
||||||
|
|
||||||
|
children.push(
|
||||||
<Breakdown.Row
|
<Breakdown.Row
|
||||||
key={id}
|
key={id}
|
||||||
type="summary"
|
type="tank"
|
||||||
title="Total"
|
tankType={tankopediaEntry?.type}
|
||||||
|
treeType={tankopediaEntry ? await getTreeType(id) : undefined}
|
||||||
|
title={await resolveTankName(id)}
|
||||||
stats={[
|
stats={[
|
||||||
{
|
{
|
||||||
title: 'Battles',
|
title: 'Battles',
|
||||||
current: currentBattles,
|
current: current.battles.toLocaleString(),
|
||||||
career: careerBattles,
|
career: career.battles.toLocaleString(),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Winrate',
|
title: 'Winrate',
|
||||||
current: `${(100 * currentWinrate).toFixed(2)}%`,
|
current: `${(100 * (current.wins / current.battles)).toFixed(
|
||||||
career: `${(100 * careerWinrate).toFixed(2)}%`,
|
2,
|
||||||
delta: currentWinrate - careerWinrate,
|
)}%`,
|
||||||
|
career: `${(100 * (career.wins / career.battles)).toFixed(2)}%`,
|
||||||
|
delta:
|
||||||
|
current.wins / current.battles - career.wins / career.battles,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'WN8',
|
title: 'WN8',
|
||||||
@@ -182,83 +228,67 @@ async function render(
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Damage',
|
title: 'Damage',
|
||||||
current: Math.round(currentDamage).toLocaleString(),
|
current: Math.round(
|
||||||
career: Math.round(careerDamage).toLocaleString(),
|
current.damage_dealt / current.battles,
|
||||||
delta: currentDamage - careerDamage,
|
).toLocaleString(),
|
||||||
|
career: Math.round(
|
||||||
|
career.damage_dealt / career.battles,
|
||||||
|
).toLocaleString(),
|
||||||
|
delta:
|
||||||
|
current.damage_dealt / current.battles -
|
||||||
|
career.damage_dealt / career.battles,
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
/>
|
/>,
|
||||||
|
);
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
{await Promise.all(
|
const pages = chunk(
|
||||||
filteredOrder.map(async (id, index) => {
|
children,
|
||||||
const tankopediaEntry = awaitedTankopedia[id];
|
Math.max(Math.ceil(children.length / MAX_PAGES), ROWS_PER_PAGE),
|
||||||
const current = orderedCurrentStats[index];
|
|
||||||
const career = orderedCareerStats[index];
|
|
||||||
const currentWN8 = orderedCurrentWN8[index];
|
|
||||||
const careerWN8 = orderedCareerWN8[index];
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Breakdown.Row
|
|
||||||
key={id}
|
|
||||||
type="tank"
|
|
||||||
tankType={tankopediaEntry?.type}
|
|
||||||
treeType={tankopediaEntry ? await getTreeType(id) : undefined}
|
|
||||||
title={await resolveTankName(id)}
|
|
||||||
stats={[
|
|
||||||
{
|
|
||||||
title: 'Battles',
|
|
||||||
current: current.battles.toLocaleString(),
|
|
||||||
career: career.battles.toLocaleString(),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Winrate',
|
|
||||||
current: `${(
|
|
||||||
100 *
|
|
||||||
(current.wins / current.battles)
|
|
||||||
).toFixed(2)}%`,
|
|
||||||
career: `${(100 * (career.wins / career.battles)).toFixed(
|
|
||||||
2,
|
|
||||||
)}%`,
|
|
||||||
delta:
|
|
||||||
current.wins / current.battles -
|
|
||||||
career.wins / career.battles,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'WN8',
|
|
||||||
current:
|
|
||||||
currentWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: Math.round(currentWN8).toLocaleString(),
|
|
||||||
career:
|
|
||||||
careerWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: Math.round(careerWN8).toLocaleString(),
|
|
||||||
percentile:
|
|
||||||
currentWN8 === undefined
|
|
||||||
? undefined
|
|
||||||
: getWN8Percentile(currentWN8),
|
|
||||||
},
|
|
||||||
{
|
|
||||||
title: 'Damage',
|
|
||||||
current: Math.round(
|
|
||||||
current.damage_dealt / current.battles,
|
|
||||||
).toLocaleString(),
|
|
||||||
career: Math.round(
|
|
||||||
career.damage_dealt / career.battles,
|
|
||||||
).toLocaleString(),
|
|
||||||
delta:
|
|
||||||
current.damage_dealt / current.battles -
|
|
||||||
career.damage_dealt / career.battles,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
}),
|
|
||||||
)}
|
|
||||||
</Breakdown.Root>
|
|
||||||
)}
|
|
||||||
</Wrapper>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (filteredOrder.length > 0) {
|
||||||
|
return pages
|
||||||
|
.map((page, index) => (
|
||||||
|
<Wrapper>
|
||||||
|
{index === 0 && (
|
||||||
|
<TitleBar
|
||||||
|
name={accountInfo.nickname}
|
||||||
|
image={
|
||||||
|
clanData?.clan
|
||||||
|
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData?.clan?.emblem_set_id}.png`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
description={`${name} • ${filterDescriptions}`}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Breakdown.Root>{page}</Breakdown.Root>
|
||||||
|
</Wrapper>
|
||||||
|
))
|
||||||
|
.reverse();
|
||||||
|
} else {
|
||||||
|
return [
|
||||||
|
<Wrapper>
|
||||||
|
<TitleBar
|
||||||
|
name={accountInfo.nickname}
|
||||||
|
image={
|
||||||
|
clanData?.clan
|
||||||
|
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData?.clan?.emblem_set_id}.png`
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
description={`${name} • ${filterDescriptions}`}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{filteredOrder.length === 0 && (
|
||||||
|
<NoData type={NoDataType.BattlesInPeriod} />
|
||||||
|
)}
|
||||||
|
</Wrapper>,
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const breakdownCommand = new Promise<CommandRegistryRaw>(
|
export const breakdownCommand = new Promise<CommandRegistryRaw>(
|
||||||
@@ -286,11 +316,11 @@ export const breakdownCommand = new Promise<CommandRegistryRaw>(
|
|||||||
...filters,
|
...filters,
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all([
|
return [
|
||||||
render(player, period, filters),
|
...(await render(player, period, filters)),
|
||||||
buttonPrimary(path, 'Refresh'),
|
buttonPrimary(path, 'Refresh'),
|
||||||
getBlitzStarsLinkButton(player.region, player.id),
|
await getBlitzStarsLinkButton(player.region, player.id),
|
||||||
]);
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: (interaction) => {
|
autocomplete: (interaction) => {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { SlashCommandBuilder } from 'discord.js';
|
|||||||
import markdownEscape from 'markdown-escape';
|
import markdownEscape from 'markdown-escape';
|
||||||
import { REGION_NAMES, Region } from '../constants/regions';
|
import { REGION_NAMES, Region } from '../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from '../core/blitz/fetchWargaming';
|
import fetchBlitz from '../core/blitz/fetchBlitz';
|
||||||
import addClanChoices from '../core/discord/addClanChoices';
|
import addClanChoices from '../core/discord/addClanChoices';
|
||||||
import addRegionChoices from '../core/discord/addRegionChoices';
|
import addRegionChoices from '../core/discord/addRegionChoices';
|
||||||
import embedInfo from '../core/discord/embedInfo';
|
import embedInfo from '../core/discord/embedInfo';
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { SlashCommandBuilder } from 'discord.js';
|
|||||||
import markdownEscape from 'markdown-escape';
|
import markdownEscape from 'markdown-escape';
|
||||||
import { REGION_NAMES, Region } from '../constants/regions';
|
import { REGION_NAMES, Region } from '../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from '../core/blitz/fetchWargaming';
|
import fetchBlitz from '../core/blitz/fetchBlitz';
|
||||||
import {
|
import {
|
||||||
AccountList,
|
AccountList,
|
||||||
usernamePattern,
|
usernamePattern,
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ export const REGION_NAMES: Record<Region, string> = {
|
|||||||
export const REGION_NAMES_SHORT: Record<Region, string> = {
|
export const REGION_NAMES_SHORT: Record<Region, string> = {
|
||||||
com: 'NA',
|
com: 'NA',
|
||||||
eu: 'EU',
|
eu: 'EU',
|
||||||
asia: 'AS',
|
asia: 'ASIA',
|
||||||
};
|
};
|
||||||
|
|
||||||
export const REGION_SUBDOMAIN_NAMES: Record<RegionSubdomain, string> = {
|
export const REGION_SUBDOMAIN_NAMES: Record<RegionSubdomain, string> = {
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
export type BlitzResponse<Data extends object> =
|
||||||
|
| {
|
||||||
|
status: 'error';
|
||||||
|
error: { field: string; message: string; code: 402; value: null };
|
||||||
|
}
|
||||||
|
| {
|
||||||
|
status: 'ok';
|
||||||
|
data: Data;
|
||||||
|
};
|
||||||
|
|
||||||
|
const MAX_CALLS_PER_SECOND = 10;
|
||||||
|
|
||||||
|
const queue: { url: string; resolve: (data: object) => void }[] = [];
|
||||||
|
let inProgress = 0;
|
||||||
|
|
||||||
|
async function manageQueue() {
|
||||||
|
if (queue.length > 0 && inProgress < MAX_CALLS_PER_SECOND) {
|
||||||
|
inProgress++;
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
inProgress--;
|
||||||
|
manageQueue();
|
||||||
|
}, 1000);
|
||||||
|
|
||||||
|
const { url, resolve } = queue.shift()!;
|
||||||
|
const data = (await fetch(url)
|
||||||
|
.then((response) => response.json())
|
||||||
|
.catch((error) => ({ status: 'error', error }))) as BlitzResponse<
|
||||||
|
typeof resolve
|
||||||
|
>;
|
||||||
|
|
||||||
|
if (data.status === 'ok') {
|
||||||
|
resolve(data.data);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Wargaming response error status:"${data.status}"`, {
|
||||||
|
cause: `Message: "${data.error.message}"\nURL: "${url}"`,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function fetchBlitz<Data extends object>(url: string) {
|
||||||
|
return new Promise<Data>((resolve) => {
|
||||||
|
queue.push({
|
||||||
|
url,
|
||||||
|
resolve(data) {
|
||||||
|
resolve(data as Data);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
manageQueue();
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -1,23 +0,0 @@
|
|||||||
export type BlitzResponse<Data extends object> =
|
|
||||||
| {
|
|
||||||
status: 'error';
|
|
||||||
error: { field: string; message: string; code: 402; value: null };
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
status: 'ok';
|
|
||||||
data: Data;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default async function fetchBlitz<Data extends object>(url: string) {
|
|
||||||
const data = (await fetch(url).then((response) =>
|
|
||||||
response.json(),
|
|
||||||
)) as BlitzResponse<Data>;
|
|
||||||
|
|
||||||
if (data.status === 'ok') {
|
|
||||||
return data.data;
|
|
||||||
} else {
|
|
||||||
throw new Error(`Wargaming response error status:"${data.status}"`, {
|
|
||||||
cause: `Message: "${data.error.message}"\nURL: "${url}"`,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from './fetchWargaming';
|
import fetchBlitz from './fetchBlitz';
|
||||||
import { normalizeIds } from './normalizeIds';
|
import { normalizeIds } from './normalizeIds';
|
||||||
|
|
||||||
interface IndividualAccountAchievements {
|
interface IndividualAccountAchievements {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from './fetchWargaming';
|
import fetchBlitz from './fetchBlitz';
|
||||||
import { normalizeIds } from './normalizeIds';
|
import { normalizeIds } from './normalizeIds';
|
||||||
|
|
||||||
export interface AllStats {
|
export interface AllStats {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from './fetchWargaming';
|
import fetchBlitz from './fetchBlitz';
|
||||||
import { normalizeExtra } from './normalizeExtra';
|
import { normalizeExtra } from './normalizeExtra';
|
||||||
import { normalizeIds } from './normalizeIds';
|
import { normalizeIds } from './normalizeIds';
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from './fetchWargaming';
|
import fetchBlitz from './fetchBlitz';
|
||||||
import { normalizeIds } from './normalizeIds';
|
import { normalizeIds } from './normalizeIds';
|
||||||
|
|
||||||
export interface IndividualClanInfo {
|
export interface IndividualClanInfo {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ import { Region } from '../../constants/regions';
|
|||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import { TanksStats } from '../../types/tanksStats';
|
import { TanksStats } from '../../types/tanksStats';
|
||||||
import { UserError } from '../blitzkrieg/userError';
|
import { UserError } from '../blitzkrieg/userError';
|
||||||
import fetchBlitz from './fetchWargaming';
|
import fetchBlitz from './fetchBlitz';
|
||||||
|
|
||||||
export default async function getTankStats(region: Region, id: number) {
|
export default async function getTankStats(region: Region, id: number) {
|
||||||
const tankStats = await fetchBlitz<TanksStats>(
|
const tankStats = await fetchBlitz<TanksStats>(
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import { Clan, ClanList } from '../../types/clanList';
|
import { Clan, ClanList } from '../../types/clanList';
|
||||||
import fetchBlitz from './fetchWargaming';
|
import fetchBlitz from './fetchBlitz';
|
||||||
|
|
||||||
export type ClanListWithRegion = (Clan & {
|
export type ClanListWithRegion = (Clan & {
|
||||||
region: 'com' | 'eu' | 'asia';
|
region: 'com' | 'eu' | 'asia';
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { Region } from '../../constants/regions';
|
import { Region } from '../../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from './fetchWargaming';
|
import fetchBlitz from './fetchBlitz';
|
||||||
|
|
||||||
interface Account {
|
interface Account {
|
||||||
nickname: string;
|
nickname: string;
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import { deburr } from 'lodash';
|
import { deburr } from 'lodash';
|
||||||
import { TreeTypeString } from '../../components/Tanks';
|
|
||||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from '../blitz/fetchWargaming';
|
import fetchBlitz from '../blitz/fetchBlitz';
|
||||||
import { context } from '../blitzkrieg/context';
|
import { context } from '../blitzkrieg/context';
|
||||||
|
|
||||||
export interface TankopediaEntry {
|
export interface TankopediaEntry {
|
||||||
@@ -16,7 +15,6 @@ export interface TankopediaEntry {
|
|||||||
type: string;
|
type: string;
|
||||||
description: string;
|
description: string;
|
||||||
}
|
}
|
||||||
type asd = TreeTypeString;
|
|
||||||
export interface Tankopedia {
|
export interface Tankopedia {
|
||||||
[id: number]: TankopediaEntry | undefined;
|
[id: number]: TankopediaEntry | undefined;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import { SlashCommandStringOption } from 'discord.js';
|
|||||||
export default function addUsernameChoices(option: SlashCommandStringOption) {
|
export default function addUsernameChoices(option: SlashCommandStringOption) {
|
||||||
return option
|
return option
|
||||||
.setName('username')
|
.setName('username')
|
||||||
.setDescription(
|
.setDescription('The username you use in Blitz')
|
||||||
'The username you use in Blitz (inferred from Discord nickname by default)',
|
|
||||||
)
|
|
||||||
.setAutocomplete(true);
|
.setAutocomplete(true);
|
||||||
}
|
}
|
||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
AutocompleteInteraction,
|
AutocompleteInteraction,
|
||||||
CacheType,
|
CacheType,
|
||||||
} from 'discord.js';
|
} from 'discord.js';
|
||||||
import { REGION_NAMES } from '../../constants/regions';
|
import { REGION_NAMES_SHORT } from '../../constants/regions';
|
||||||
import searchPlayersAcrossRegions from '../blitz/searchPlayersAcrossRegions';
|
import searchPlayersAcrossRegions from '../blitz/searchPlayersAcrossRegions';
|
||||||
|
|
||||||
export default async function autocompleteUsername(
|
export default async function autocompleteUsername(
|
||||||
@@ -19,7 +19,9 @@ export default async function autocompleteUsername(
|
|||||||
? players.map(
|
? players.map(
|
||||||
(player) =>
|
(player) =>
|
||||||
({
|
({
|
||||||
name: `${player.nickname} (${REGION_NAMES[player.region]})`,
|
name: `${player.nickname} (${
|
||||||
|
REGION_NAMES_SHORT[player.region]
|
||||||
|
})`,
|
||||||
value: `${player.region}/${player.account_id}`,
|
value: `${player.region}/${player.account_id}`,
|
||||||
}) satisfies ApplicationCommandOptionChoiceData<string>,
|
}) satisfies ApplicationCommandOptionChoiceData<string>,
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import jsxToPngThreaded from '../blitzkrieg/jsxToPngThreaded';
|
|||||||
export default async function normalizeInteractionReturnable(
|
export default async function normalizeInteractionReturnable(
|
||||||
returnable: InteractionReturnable,
|
returnable: InteractionReturnable,
|
||||||
) {
|
) {
|
||||||
|
const images: [number, Buffer][] = [];
|
||||||
const reply: InteractionEditReplyOptions = {};
|
const reply: InteractionEditReplyOptions = {};
|
||||||
|
|
||||||
const awaitedReturnable = await returnable;
|
const awaitedReturnable = await returnable;
|
||||||
@@ -19,7 +20,7 @@ export default async function normalizeInteractionReturnable(
|
|||||||
: [awaitedReturnable];
|
: [awaitedReturnable];
|
||||||
|
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
normalizedReturnable.map(async (item) => {
|
normalizedReturnable.map(async (item, index) => {
|
||||||
if (typeof item === 'string') {
|
if (typeof item === 'string') {
|
||||||
reply.content = item;
|
reply.content = item;
|
||||||
} else if (item instanceof EmbedBuilder) {
|
} else if (item instanceof EmbedBuilder) {
|
||||||
@@ -38,11 +39,16 @@ export default async function normalizeInteractionReturnable(
|
|||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
const image = await jsxToPngThreaded(item);
|
const image = await jsxToPngThreaded(item);
|
||||||
if (!reply.files) reply.files = [];
|
images.push([index, image]);
|
||||||
reply.files.push(image);
|
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (images.length > 0) {
|
||||||
|
images.sort(([a], [b]) => b - a);
|
||||||
|
if (!reply.files) reply.files = [];
|
||||||
|
images.forEach(([, image]) => reply.files?.push(image));
|
||||||
|
}
|
||||||
|
|
||||||
return reply;
|
return reply;
|
||||||
}
|
}
|
||||||
@@ -4,7 +4,7 @@ import { devtools, persist } from 'zustand/middleware';
|
|||||||
import { CustomColumnDisplay } from '../app/tools/session/components/CustomColumn';
|
import { CustomColumnDisplay } from '../app/tools/session/components/CustomColumn';
|
||||||
import { Region } from '../constants/regions';
|
import { Region } from '../constants/regions';
|
||||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||||
import fetchBlitz from '../core/blitz/fetchWargaming';
|
import fetchBlitz from '../core/blitz/fetchBlitz';
|
||||||
import { NormalizedTankStats, TanksStats } from '../types/tanksStats';
|
import { NormalizedTankStats, TanksStats } from '../types/tanksStats';
|
||||||
|
|
||||||
type Session = (
|
type Session = (
|
||||||
|
|||||||
Reference in new issue
Block a user