mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: swap core and _core
This commit is contained in:
1 parent
07e3660388
commit
b827f7f730
113 files changed
+254
-247
No files matched your search
@@ -0,0 +1,26 @@
|
||||
import throwError from '../../LEGACY_core/node/throwError';
|
||||
|
||||
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 throwError(
|
||||
`Wargaming response error status:"${data.status}"`,
|
||||
`Message: "${data.error.message}"\nURL: "${url}"`,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import fetchBlitz from './fetchWargaming';
|
||||
import { normalizeIds } from './normalizeIds';
|
||||
|
||||
interface IndividualAccountAchievements {
|
||||
achievements: {
|
||||
[achievement: string]: number;
|
||||
};
|
||||
max_series: {
|
||||
[achievement: string]: number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AccountAchievements {
|
||||
[id: number]: IndividualAccountAchievements;
|
||||
}
|
||||
|
||||
export async function getAccountAchievements<
|
||||
Ids extends number | number[],
|
||||
ReturnType = Ids extends number
|
||||
? IndividualAccountAchievements
|
||||
: IndividualAccountAchievements[],
|
||||
>(region: Region, ids: Ids) {
|
||||
const object = await fetchBlitz<AccountAchievements>(
|
||||
`https://api.wotblitz.${region}/wotb/account/achievements/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${normalizeIds(
|
||||
ids,
|
||||
)}`,
|
||||
);
|
||||
|
||||
if (typeof ids === 'number') {
|
||||
return object[ids as number] as ReturnType;
|
||||
} else {
|
||||
return ids.map((id) => object[id]) as ReturnType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import fetchBlitz from './fetchWargaming';
|
||||
import { normalizeIds } from './normalizeIds';
|
||||
|
||||
export interface AllStats {
|
||||
spotted: number;
|
||||
hits: number;
|
||||
frags: number;
|
||||
max_xp: number;
|
||||
wins: number;
|
||||
losses: number;
|
||||
capture_points: number;
|
||||
battles: number;
|
||||
damage_dealt: number;
|
||||
damage_received: number;
|
||||
max_frags: number;
|
||||
shots: number;
|
||||
frags8p: number;
|
||||
xp: number;
|
||||
win_and_survived: number;
|
||||
survived_battles: number;
|
||||
dropped_capture_points: number;
|
||||
}
|
||||
|
||||
export interface SupplementaryStats {
|
||||
// if undefined, WN8 is not available for tanks without averages
|
||||
WN8?: number;
|
||||
tier?: number;
|
||||
}
|
||||
|
||||
export interface ClanStats {
|
||||
spotted: number;
|
||||
max_frags_tank_id: number;
|
||||
hits: number;
|
||||
frags: number;
|
||||
max_xp: number;
|
||||
max_xp_tank_id: number;
|
||||
wins: number;
|
||||
losses: number;
|
||||
capture_points: number;
|
||||
battles: number;
|
||||
damage_dealt: number;
|
||||
damage_received: number;
|
||||
max_frags: number;
|
||||
shots: number;
|
||||
frags8p: number;
|
||||
xp: number;
|
||||
win_and_survived: number;
|
||||
survived_battles: number;
|
||||
dropped_capture_points: number;
|
||||
}
|
||||
|
||||
interface IndividualAccountInfo {
|
||||
account_id: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
private: null;
|
||||
last_battle_time: number;
|
||||
nickname: string;
|
||||
statistics: {
|
||||
all: AllStats;
|
||||
clan: ClanStats;
|
||||
frags: null | number;
|
||||
};
|
||||
}
|
||||
|
||||
export interface AccountInfo {
|
||||
[accountId: number]: IndividualAccountInfo;
|
||||
}
|
||||
|
||||
export async function getAccountInfo<
|
||||
Ids extends number | number[],
|
||||
ReturnType = Ids extends number
|
||||
? IndividualAccountInfo
|
||||
: IndividualAccountInfo[],
|
||||
>(region: Region, ids: Ids) {
|
||||
const object = await fetchBlitz<AccountInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${normalizeIds(
|
||||
ids,
|
||||
)}`,
|
||||
);
|
||||
|
||||
if (typeof ids === 'number') {
|
||||
return object[ids as number] as ReturnType;
|
||||
} else {
|
||||
return ids.map((id) => object[id]) as ReturnType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import fetchBlitz from './fetchWargaming';
|
||||
import { normalizeExtra } from './normalizeExtra';
|
||||
import { normalizeIds } from './normalizeIds';
|
||||
|
||||
export type IndividualClanAccountInfo = {
|
||||
account_id: number;
|
||||
joined_at: number;
|
||||
clan_id: number;
|
||||
role: string;
|
||||
account_name: string;
|
||||
|
||||
clan?: {
|
||||
members_count: number;
|
||||
name: string;
|
||||
created_at: number;
|
||||
tag: string;
|
||||
clan_id: number;
|
||||
emblem_set_id: number;
|
||||
};
|
||||
} | null;
|
||||
|
||||
export interface ClanAccountInfo {
|
||||
[accountId: number]: IndividualClanAccountInfo;
|
||||
}
|
||||
|
||||
export async function getClanAccountInfo<
|
||||
Ids extends number | number[],
|
||||
ReturnType = Ids extends number
|
||||
? IndividualClanAccountInfo
|
||||
: IndividualClanAccountInfo[],
|
||||
>(region: Region, ids: Ids, extra?: string[]) {
|
||||
const object = await fetchBlitz<ClanAccountInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${normalizeIds(
|
||||
ids,
|
||||
)}${normalizeExtra(extra)}`,
|
||||
);
|
||||
|
||||
if (typeof ids === 'number') {
|
||||
return object[ids as number] as ReturnType;
|
||||
} else {
|
||||
return ids.map((id) => object[id]) as ReturnType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import fetchBlitz from './fetchWargaming';
|
||||
import { normalizeIds } from './normalizeIds';
|
||||
|
||||
export interface IndividualClanInfo {
|
||||
recruiting_options: {
|
||||
vehicles_level: number;
|
||||
wins_ratio: number;
|
||||
average_battles_per_day: number;
|
||||
battles: number;
|
||||
average_damage: number;
|
||||
};
|
||||
members_count: number;
|
||||
name: string;
|
||||
creator_name: string;
|
||||
clan_id: number;
|
||||
created_at: number;
|
||||
updated_at: number;
|
||||
leader_name: string;
|
||||
members_ids: number[];
|
||||
recruiting_policy: string;
|
||||
tag: string;
|
||||
is_clan_disbanded: boolean;
|
||||
old_name: string;
|
||||
emblem_set_id: number;
|
||||
creator_id: number;
|
||||
motto: string;
|
||||
renamed_at: number;
|
||||
old_tag: null;
|
||||
leader_id: number;
|
||||
description: string;
|
||||
}
|
||||
|
||||
export interface ClanInfo {
|
||||
[clanId: number]: IndividualClanInfo;
|
||||
}
|
||||
|
||||
export async function getClanInfo<
|
||||
Ids extends number | number[],
|
||||
ReturnType = Ids extends number ? IndividualClanInfo : IndividualClanInfo[],
|
||||
>(region: Region, ids: Ids) {
|
||||
const object = await fetchBlitz<ClanInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${normalizeIds(
|
||||
ids,
|
||||
)}`,
|
||||
);
|
||||
|
||||
if (typeof ids === 'number') {
|
||||
return object[ids as number] as ReturnType;
|
||||
} else {
|
||||
return ids.map((id) => object[id]) as ReturnType;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
import { RatingsInfo } from '../../commands/ratings';
|
||||
import { Region } from '../../constants/regions';
|
||||
import regionToRegionSubdomain from '../../LEGACY_core/blitz/regionToRegionSubdomain';
|
||||
|
||||
export default async function getRatingsInfo(region: Region) {
|
||||
const response = await fetch(
|
||||
`https://${regionToRegionSubdomain(
|
||||
region,
|
||||
)}.wotblitz.com/en/api/rating-leaderboards/season/`,
|
||||
);
|
||||
|
||||
return (await response.json()) as Promise<RatingsInfo>;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import throwError from '../../LEGACY_core/node/throwError';
|
||||
import { TanksStats } from '../../types/tanksStats';
|
||||
import fetchBlitz from './fetchWargaming';
|
||||
|
||||
export default async function getTankStats(region: Region, id: number) {
|
||||
const tankStats = await fetchBlitz<TanksStats>(
|
||||
`https://api.wotblitz.${region}/wotb/tanks/stats/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
|
||||
if (tankStats[id] === null) {
|
||||
throw throwError(
|
||||
'No tank stats available',
|
||||
"This player doesn't have any stats for tanks available. This may not be the player you are looking for.",
|
||||
);
|
||||
}
|
||||
|
||||
return tankStats[id];
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
import { TreeTypeEnum } from '../../components/Tanks';
|
||||
import { tankopedia } from '../../LEGACY_core/blitz/tankopedia';
|
||||
|
||||
export default async function getTreeType(id: number) {
|
||||
const entry = (await tankopedia)[id];
|
||||
|
||||
if (entry?.is_collectible) return TreeTypeEnum.Collector;
|
||||
if (entry?.is_premium) return TreeTypeEnum.Premium;
|
||||
|
||||
return TreeTypeEnum.TechTree;
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
import { Percentile } from '../../constants/percentiles';
|
||||
|
||||
export const WN8_PERCENTILES: [number, Percentile][] = [
|
||||
[0, Percentile.VeryBad],
|
||||
[300, Percentile.Bad],
|
||||
[450, Percentile.BelowAverage],
|
||||
[650, Percentile.Average],
|
||||
[900, Percentile.AboveAverage],
|
||||
[1200, Percentile.Good],
|
||||
[1600, Percentile.VeryGood],
|
||||
[2000, Percentile.Great],
|
||||
[2450, Percentile.Unicum],
|
||||
[2900, Percentile.SuperUnicum],
|
||||
];
|
||||
|
||||
export default function getWN8Percentile(WN8: number) {
|
||||
const lastIndex = WN8_PERCENTILES.findLastIndex(
|
||||
([WN8Listing]) => WN8Listing <= WN8,
|
||||
);
|
||||
return WN8_PERCENTILES[lastIndex === -1 ? 0 : lastIndex][1];
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
import fetchBlitz from '../../_core/blitz/fetchWargaming';
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import { Clan, ClanList } from '../../types/clanList';
|
||||
|
||||
export type ClanListWithRegion = (Clan & {
|
||||
region: 'com' | 'eu' | 'asia';
|
||||
})[];
|
||||
|
||||
export default async function listClans(search: string, limit = 9) {
|
||||
const trimmed = search.trim();
|
||||
if (trimmed.length < 3 && trimmed.length > 100) return [];
|
||||
const normalizedLimit = Math.round(limit / 3);
|
||||
|
||||
return (
|
||||
await Promise.all([
|
||||
fetchBlitz<ClanList>(
|
||||
`https://api.wotblitz.com/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${search}&limit=${normalizedLimit}`,
|
||||
).then(
|
||||
(value) =>
|
||||
value &&
|
||||
value.map((account) => ({
|
||||
...account,
|
||||
region: 'com' as Region,
|
||||
})),
|
||||
),
|
||||
fetchBlitz<ClanList>(
|
||||
`https://api.wotblitz.eu/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${search}&limit=${normalizedLimit}`,
|
||||
).then(
|
||||
(value) =>
|
||||
value &&
|
||||
value.map((account) => ({
|
||||
...account,
|
||||
region: 'eu' as Region,
|
||||
})),
|
||||
),
|
||||
fetchBlitz<ClanList>(
|
||||
`https://api.wotblitz.asia/wotb/clans/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${search}&limit=${normalizedLimit}`,
|
||||
).then(
|
||||
(value) =>
|
||||
value &&
|
||||
value.map((account) => ({
|
||||
...account,
|
||||
region: 'asia' as Region,
|
||||
})),
|
||||
),
|
||||
])
|
||||
)
|
||||
.filter(Boolean)
|
||||
.flat();
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
import fetchBlitz from '../../_core/blitz/fetchWargaming';
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
|
||||
interface Account {
|
||||
nickname: string;
|
||||
account_id: number;
|
||||
}
|
||||
export type AccountList = Account[];
|
||||
export type AccountListWithServer = (Account & {
|
||||
region: Region;
|
||||
})[];
|
||||
|
||||
export const usernamePattern = /^[a-zA-Z0-9_]{3,24}$/;
|
||||
export const usernamePatternWithoutPosition = /[a-zA-Z0-9_]{3,24}/;
|
||||
|
||||
export default async function listPlayers(search: string, limit = 9) {
|
||||
const trimmedSearch = search.trim();
|
||||
const normalizedLimit = Math.round(limit / 3);
|
||||
const encodedSearch = encodeURIComponent(trimmedSearch);
|
||||
|
||||
if (usernamePattern.test(trimmedSearch)) {
|
||||
return (
|
||||
await Promise.all([
|
||||
fetchBlitz<AccountList>(
|
||||
`https://api.wotblitz.com/wotb/account/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${encodedSearch}&limit=${normalizedLimit}`,
|
||||
).then(
|
||||
(value) =>
|
||||
value &&
|
||||
value.map((account) => ({
|
||||
...account,
|
||||
region: 'com' as Region,
|
||||
})),
|
||||
),
|
||||
fetchBlitz<AccountList>(
|
||||
`https://api.wotblitz.eu/wotb/account/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${encodedSearch}&limit=${normalizedLimit}`,
|
||||
).then(
|
||||
(value) =>
|
||||
value &&
|
||||
value.map((account) => ({
|
||||
...account,
|
||||
region: 'eu' as Region,
|
||||
})),
|
||||
),
|
||||
fetchBlitz<AccountList>(
|
||||
`https://api.wotblitz.asia/wotb/account/list/?application_id=${WARGAMING_APPLICATION_ID}&search=${encodedSearch}&limit=${normalizedLimit}`,
|
||||
).then(
|
||||
(value) =>
|
||||
value &&
|
||||
value.map((account) => ({
|
||||
...account,
|
||||
region: 'asia' as Region,
|
||||
})),
|
||||
),
|
||||
])
|
||||
)
|
||||
.filter(Boolean)
|
||||
.flat() as AccountListWithServer;
|
||||
} else {
|
||||
return [] as AccountListWithServer;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function normalizeExtra(extra?: string[]) {
|
||||
return extra ? `&extra=${extra.join(',')}` : '';
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export function normalizeIds(ids: number | number[]): string {
|
||||
return typeof ids === 'number' ? ids.toString() : ids.join(',');
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
/**
|
||||
* Thanks, August!
|
||||
* https://stackoverflow.com/a/41358305/12294756
|
||||
*/
|
||||
const ROMAN = {
|
||||
M: 1000,
|
||||
CM: 900,
|
||||
D: 500,
|
||||
CD: 400,
|
||||
C: 100,
|
||||
XC: 90,
|
||||
L: 50,
|
||||
XL: 40,
|
||||
X: 10,
|
||||
IX: 9,
|
||||
V: 5,
|
||||
IV: 4,
|
||||
I: 1,
|
||||
};
|
||||
const ROMAN_KEYS = Object.keys(ROMAN) as (keyof typeof ROMAN)[];
|
||||
|
||||
export default function numberToRomanNumeral(value: number) {
|
||||
let string = '';
|
||||
|
||||
ROMAN_KEYS.forEach((index) => {
|
||||
const part = Math.floor(value / ROMAN[index]);
|
||||
value -= part * ROMAN[index];
|
||||
string += index.repeat(part);
|
||||
});
|
||||
|
||||
return string;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { Region, RegionSubdomain } from '../../constants/regions';
|
||||
|
||||
export default function regionToRegionSubdomain(
|
||||
regionDomain: Region,
|
||||
): RegionSubdomain {
|
||||
return regionDomain === 'com' ? 'na' : regionDomain;
|
||||
}
|
||||
@@ -1,29 +0,0 @@
|
||||
import { go } from 'fuzzysort';
|
||||
import throwError from '../node/throwError';
|
||||
import { TANKS, tankopedia } from './tankopedia';
|
||||
|
||||
export default async function resolveTankId(tank: string) {
|
||||
const number = parseInt(tank);
|
||||
|
||||
if (Number.isNaN(number)) {
|
||||
const searchResult = go(tank, await TANKS, { keys: ['name'], limit: 1 });
|
||||
|
||||
if (searchResult.length === 0) {
|
||||
throw throwError(
|
||||
'Tank not found',
|
||||
`Could not find tank by the name "${tank}".`,
|
||||
);
|
||||
} else {
|
||||
return searchResult[0].obj.tank_id;
|
||||
}
|
||||
} else {
|
||||
if ((await tankopedia)[number]) {
|
||||
return number;
|
||||
} else {
|
||||
throw throwError(
|
||||
'Tank not found',
|
||||
`Could not find tank by the ID "${number}".`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
import { tankopedia } from './tankopedia';
|
||||
|
||||
export default async function resolveTankName(tankId: number) {
|
||||
const tankopediaName = (await tankopedia)[tankId]?.name;
|
||||
return tankopediaName ? tankopediaName : `Unknown Tank ${tankId}`;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
import { AllStats } from '../../_core/blitz/getAccountInfo';
|
||||
import { emptyAllStats } from '../blitzstars/getDiffedTankStats';
|
||||
|
||||
export default function sumStats(allStatsCollection: AllStats[]) {
|
||||
return allStatsCollection.reduce((accumulated, current) => {
|
||||
function sum(value: (allStats: AllStats) => number) {
|
||||
return value(accumulated) + value(current);
|
||||
}
|
||||
function max(value: (allStats: AllStats) => number) {
|
||||
return Math.max(value(accumulated), value(current));
|
||||
}
|
||||
|
||||
return {
|
||||
battles: sum((a) => a.battles),
|
||||
wins: sum((a) => a.wins),
|
||||
capture_points: sum((a) => a.capture_points),
|
||||
damage_dealt: sum((a) => a.damage_dealt),
|
||||
damage_received: sum((a) => a.damage_received),
|
||||
dropped_capture_points: sum((a) => a.dropped_capture_points),
|
||||
frags: sum((a) => a.frags),
|
||||
frags8p: sum((a) => a.frags8p),
|
||||
hits: sum((a) => a.hits),
|
||||
losses: sum((a) => a.losses),
|
||||
max_frags: max((a) => a.max_frags),
|
||||
max_xp: max((a) => a.max_xp),
|
||||
shots: sum((a) => a.shots),
|
||||
spotted: sum((a) => a.spotted),
|
||||
survived_battles: sum((a) => a.survived_battles),
|
||||
win_and_survived: sum((a) => a.win_and_survived),
|
||||
xp: sum((a) => a.xp),
|
||||
} satisfies AllStats;
|
||||
}, emptyAllStats);
|
||||
}
|
||||
@@ -1,113 +0,0 @@
|
||||
import { deburr } from 'lodash';
|
||||
import fetchBlitz from '../../_core/blitz/fetchWargaming';
|
||||
import { TreeTypeString } from '../../components/Tanks';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import { context } from '../blitzkrieg/context';
|
||||
|
||||
export interface TankopediaEntry {
|
||||
name: string;
|
||||
nation: string;
|
||||
is_premium: boolean;
|
||||
is_collectible: boolean;
|
||||
tier: Tier;
|
||||
cost: { price_credit: number; price_gold: number };
|
||||
images: { preview: string; normal: string };
|
||||
tank_id: number;
|
||||
type: string;
|
||||
description: string;
|
||||
}
|
||||
type asd = TreeTypeString;
|
||||
export interface Tankopedia {
|
||||
[id: number]: TankopediaEntry | undefined;
|
||||
}
|
||||
|
||||
console.log('Caching tankopedia...');
|
||||
export const tankopedia = fetch(
|
||||
context === 'bot'
|
||||
? 'https://www.blitzstars.com/bs-tankopedia.json'
|
||||
: '/api/tankopedia',
|
||||
)
|
||||
.then(async (response) => response.json())
|
||||
.then((wrapperTankopedia) => {
|
||||
console.log('Tankopedia cached');
|
||||
return context === 'bot'
|
||||
? (wrapperTankopedia as { data: Tankopedia }).data
|
||||
: (wrapperTankopedia as Tankopedia);
|
||||
});
|
||||
const entries = new Promise<TankopediaEntry[]>(async (resolve) => {
|
||||
resolve(Object.entries(await tankopedia).map(([, entry]) => entry));
|
||||
});
|
||||
export const TANKS = new Promise<TankopediaEntry[]>(async (resolve) => {
|
||||
resolve((await entries).map((entry) => entry));
|
||||
});
|
||||
export const TANK_NAMES = new Promise<string[]>(async (resolve) => {
|
||||
resolve((await entries).map(({ name }) => name));
|
||||
});
|
||||
export const TANK_NAMES_DIACRITICS = TANK_NAMES.then((tankNames) =>
|
||||
Promise.all(
|
||||
tankNames.map(async (tankName, index) => {
|
||||
const id = (await TANKS)[index].tank_id;
|
||||
const name = tankName ?? `Unknown Tank ${id}`;
|
||||
const diacriticless = deburr(name);
|
||||
|
||||
return {
|
||||
original: name,
|
||||
diacriticless,
|
||||
combined: `${name}${diacriticless}`,
|
||||
id,
|
||||
};
|
||||
}),
|
||||
),
|
||||
);
|
||||
|
||||
export interface TankopediaInfo {
|
||||
achievement_sections: Record<string, { name: string; order: number }>;
|
||||
tanks_updated_at: number;
|
||||
languages: Record<string, string>;
|
||||
vehicle_types: Record<string, string>;
|
||||
vehicle_nations: Record<string, string>;
|
||||
game_version: string;
|
||||
}
|
||||
|
||||
// this is blocking because info is needed for command creation
|
||||
console.log('Caching tankopedia info...');
|
||||
export const tankopediaInfo = fetchBlitz<TankopediaInfo>(
|
||||
`https://api.wotblitz.com/wotb/encyclopedia/info/?application_id=${WARGAMING_APPLICATION_ID}`,
|
||||
);
|
||||
console.log('Cached tankopedia info');
|
||||
|
||||
export const TANK_ICONS: Record<string, string> = {
|
||||
'AT-SPG': 'https://i.imgur.com/BIHSEH0.png',
|
||||
lightTank: 'https://i.imgur.com/CSNha5V.png',
|
||||
mediumTank: 'https://i.imgur.com/wvf3ltm.png',
|
||||
heavyTank: 'https://i.imgur.com/ECeqlZa.png',
|
||||
};
|
||||
|
||||
export const TANK_ICONS_PREMIUM: Record<string, string> = {
|
||||
'AT-SPG': 'https://i.imgur.com/TCu3EdR.png',
|
||||
lightTank: 'https://i.imgur.com/zdkpTRb.png',
|
||||
mediumTank: 'https://i.imgur.com/3z7eHX6.png',
|
||||
heavyTank: 'https://i.imgur.com/P3vbmyA.png',
|
||||
};
|
||||
|
||||
export const TANK_ICONS_COLLECTOR: Record<string, string> = {
|
||||
'AT-SPG': 'https://i.imgur.com/WTjeirB.png',
|
||||
lightTank: 'https://i.imgur.com/EwhtKkU.png',
|
||||
mediumTank: 'https://i.imgur.com/u8YDMBh.png',
|
||||
heavyTank: 'https://i.imgur.com/8xRf3nc.png',
|
||||
};
|
||||
|
||||
export type Tier = 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10;
|
||||
|
||||
export const TIER_ROMAN_NUMERALS: Record<Tier, string> = {
|
||||
1: 'I',
|
||||
2: 'II',
|
||||
3: 'III',
|
||||
4: 'IV',
|
||||
5: 'V',
|
||||
6: 'VI',
|
||||
7: 'VII',
|
||||
8: 'VIII',
|
||||
9: 'IX',
|
||||
10: 'X',
|
||||
};
|
||||
Reference in new issue
Block a user