mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 03:29:51 +02:00
Merge branch 'main' into dev
This commit is contained in:
commit
23a33c7722
45 files changed
+743
-504
No files matched your search
@@ -4,7 +4,11 @@ import { context } from '../blitzkrieg/context';
|
||||
import { patientFetch } from '../blitzkrieg/patientFetch';
|
||||
import regionToRegionSubdomain from './regionToRegionSubdomain';
|
||||
|
||||
const ratingsInfoCache: Partial<Record<Region, RatingsInfo>> = {};
|
||||
|
||||
export default async function getRatingsInfo(region: Region) {
|
||||
if (ratingsInfoCache[region]) return ratingsInfoCache[region]!;
|
||||
|
||||
const response = await patientFetch(
|
||||
context === 'website'
|
||||
? `/api/${region}/ratings/current/info`
|
||||
@@ -14,6 +18,9 @@ export default async function getRatingsInfo(region: Region) {
|
||||
undefined,
|
||||
{ cache: 'no-store' },
|
||||
);
|
||||
const data = (await response.json()) as RatingsInfo;
|
||||
|
||||
return (await response.json()) as Promise<RatingsInfo>;
|
||||
ratingsInfoCache[region] = data;
|
||||
|
||||
return data;
|
||||
}
|
||||
@@ -10,10 +10,9 @@ export default async function getTankStats(region: Region, id: number) {
|
||||
);
|
||||
|
||||
if (tankStats[id] === null) {
|
||||
throw new UserError('No tank stats available', {
|
||||
cause:
|
||||
"This player doesn't have any stats for tanks available. This may not be the player you are looking for.",
|
||||
});
|
||||
throw new UserError(
|
||||
"# No tank stats available\nThis player doesn't have any stats available. This may not be the player you are looking for.",
|
||||
);
|
||||
}
|
||||
|
||||
return tankStats[id];
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
import getRatingsInfo from './getRatingsInfo';
|
||||
|
||||
export async function isOnGoingRatingsSeason() {
|
||||
const ratingsInfo = await getRatingsInfo('com');
|
||||
return ratingsInfo.detail === undefined;
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { go } from 'fuzzysort';
|
||||
import { UserError } from '../../hooks/userError';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import {
|
||||
tankDefinitions,
|
||||
tanksDefinitionsArray,
|
||||
@@ -15,9 +16,9 @@ export default async function resolveTankId(tank: string | number) {
|
||||
});
|
||||
|
||||
if (searchResult.length === 0) {
|
||||
throw new UserError('Tank not found', {
|
||||
cause: `Could not find tank by the name "${tank}".`,
|
||||
});
|
||||
throw new UserError(
|
||||
`# Tank not found\nCould not find tank by the name "${markdownEscape(`${tank}`)}".`,
|
||||
);
|
||||
} else {
|
||||
return searchResult[0].obj.id;
|
||||
}
|
||||
@@ -25,9 +26,9 @@ export default async function resolveTankId(tank: string | number) {
|
||||
if ((await tankDefinitions)[number]) {
|
||||
return number;
|
||||
} else {
|
||||
throw new UserError('Tank not found', {
|
||||
cause: `Could not find tank by the ID "${number}".`,
|
||||
});
|
||||
throw new UserError(
|
||||
`# Tank not found\nCould not find tank by the ID "${number}". Try typing the name of the tank instead of a number.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,28 @@
|
||||
import getRatingsInfo from '../blitz/getRatingsInfo';
|
||||
|
||||
interface GitHubTrees {
|
||||
tree: { path: string; url: string }[];
|
||||
}
|
||||
|
||||
let cachedLatestArchivedSeasonNumber: number | null = null;
|
||||
|
||||
export async function getArchivedLatestSeasonNumber() {
|
||||
if (cachedLatestArchivedSeasonNumber !== null) {
|
||||
return cachedLatestArchivedSeasonNumber;
|
||||
}
|
||||
|
||||
const ratingsInfo = await getRatingsInfo('com');
|
||||
|
||||
if (ratingsInfo.detail) {
|
||||
const comURL = (
|
||||
const regionsURL = (
|
||||
(await fetch(
|
||||
'https://api.github.com/repos/tresabhi/blitzkrieg-assets/git/trees/main/regions',
|
||||
).then((response) => response.json())) as {
|
||||
tree: { path: string; url: string }[];
|
||||
}
|
||||
'https://api.github.com/repos/tresabhi/blitzkrieg-assets/git/trees/main',
|
||||
).then((response) => response.json())) as GitHubTrees
|
||||
).tree.find(({ path }) => path === 'regions')!.url;
|
||||
const comURL = (
|
||||
(await fetch(regionsURL).then((response) =>
|
||||
response.json(),
|
||||
)) as GitHubTrees
|
||||
).tree.find(({ path }) => path === 'com')!.url;
|
||||
const ratingsURL = (
|
||||
(await fetch(comURL).then((response) => response.json())) as {
|
||||
@@ -20,14 +31,16 @@ export async function getArchivedLatestSeasonNumber() {
|
||||
).tree[0].url;
|
||||
const latestSeason = Math.max(
|
||||
...(
|
||||
(await fetch(ratingsURL).then((response) => {
|
||||
response.json();
|
||||
})) as { tree: { path: string }[] }
|
||||
).tree.map(({ path }) => parseInt(path)),
|
||||
(await fetch(ratingsURL).then((response) => response.json())) as {
|
||||
tree: { path: string }[];
|
||||
}
|
||||
).tree.map(({ path }) => Number(path)),
|
||||
);
|
||||
|
||||
return latestSeason;
|
||||
cachedLatestArchivedSeasonNumber = latestSeason;
|
||||
} else {
|
||||
return ratingsInfo.current_season - 1;
|
||||
cachedLatestArchivedSeasonNumber = ratingsInfo.current_season - 1;
|
||||
}
|
||||
|
||||
return cachedLatestArchivedSeasonNumber;
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
import {
|
||||
SlashCommandBuilder,
|
||||
SlashCommandSubcommandBuilder,
|
||||
SlashCommandSubcommandGroupBuilder,
|
||||
} from 'discord.js';
|
||||
import { encyclopediaInfo } from '../blitz/encyclopediaInfo';
|
||||
import { addFilterOptions } from './addFilterOptions';
|
||||
import addPeriodSubCommands from './addPeriodSubCommands';
|
||||
|
||||
export default async function addPeriodicFilterOptions<
|
||||
OptionType extends SlashCommandBuilder | SlashCommandSubcommandGroupBuilder,
|
||||
>(
|
||||
option: OptionType,
|
||||
extra: (
|
||||
option: SlashCommandSubcommandBuilder,
|
||||
) => SlashCommandSubcommandBuilder = (option) => option,
|
||||
): Promise<OptionType> {
|
||||
const awaitedEncyclopediaInfo = await encyclopediaInfo;
|
||||
|
||||
addPeriodSubCommands(option, (option) => {
|
||||
return addFilterOptions(extra(option), awaitedEncyclopediaInfo);
|
||||
});
|
||||
|
||||
return option;
|
||||
}
|
||||
@@ -3,12 +3,17 @@ import { PeriodType } from './addPeriodSubCommands';
|
||||
|
||||
export function getCustomPeriodParams(
|
||||
interaction: ChatInputCommandInteraction,
|
||||
forcedNonCustomPeriod = false,
|
||||
) {
|
||||
if ((interaction.options.getSubcommand() as PeriodType) === 'custom')
|
||||
if (
|
||||
!forcedNonCustomPeriod &&
|
||||
(interaction.options.getSubcommand() as PeriodType) === 'custom'
|
||||
) {
|
||||
return {
|
||||
start: interaction.options.getInteger('start', true),
|
||||
end: interaction.options.getInteger('end', true),
|
||||
};
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
@@ -1,4 +1,5 @@
|
||||
import { ChatInputCommandInteraction } from 'discord.js';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { Region } from '../../constants/regions';
|
||||
import { UserError } from '../../hooks/userError';
|
||||
import searchClansAcrossRegions from '../blitz/searchClansAcrossRegions';
|
||||
@@ -18,9 +19,9 @@ export default async function resolveClanFromCommand(
|
||||
if (accounts[0]) {
|
||||
return { region: accounts[0].region, id: accounts[0].clan_id };
|
||||
} else {
|
||||
throw new UserError('Could not find clan', {
|
||||
cause: `I couldn't find clan \`${clan}\`. Try selecting a username from the search result.`,
|
||||
});
|
||||
throw new UserError(
|
||||
`# Could not find clan\nCouldn't find "${markdownEscape(clan)}". Try selecting a clan from the search result.`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,11 +20,14 @@ export interface ResolvedPeriod {
|
||||
export default function resolvePeriodFromCommand(
|
||||
region: Region,
|
||||
interaction: ChatInputCommandInteraction<CacheType>,
|
||||
forcedPeriod?: PeriodType,
|
||||
) {
|
||||
let name: string;
|
||||
let start: number;
|
||||
let end: number;
|
||||
const periodSubcommand = interaction.options.getSubcommand() as PeriodType;
|
||||
const periodSubcommand = forcedPeriod
|
||||
? forcedPeriod
|
||||
: (interaction.options.getSubcommand() as PeriodType);
|
||||
|
||||
if (periodSubcommand === 'custom') {
|
||||
const startOption = interaction.options.getInteger('start', true);
|
||||
|
||||
@@ -34,11 +34,11 @@ export default async function resolvePlayerFromCommand(
|
||||
id: accounts[0].account_id,
|
||||
} satisfies ResolvedPlayer;
|
||||
} else {
|
||||
throw new UserError('Could not find user', {
|
||||
cause: `I couldn't find user "${markdownEscape(
|
||||
throw new UserError(
|
||||
`# Could not find user\nI couldn't find user "${markdownEscape(
|
||||
commandUsername,
|
||||
)}". Try picking an user from the search result, typing in a valid username, or using the \`/link\` command.`,
|
||||
});
|
||||
);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@@ -47,9 +47,9 @@ export default async function resolvePlayerFromCommand(
|
||||
if (account) {
|
||||
return { region: account.region, id: account.blitz };
|
||||
} else {
|
||||
throw new UserError('Use the `/link` command', {
|
||||
cause: 'Link your Blitz and Discord accounts to get started.',
|
||||
});
|
||||
throw new UserError(
|
||||
"# I don't know who you are\nUse the `/link` command to get started.",
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,12 +4,19 @@ import {
|
||||
emptyIndividualTankStats,
|
||||
} from '../../types/tanksStats';
|
||||
|
||||
export function deltaTankStats(a: NormalizedTankStats, b: NormalizedTankStats) {
|
||||
export function deltaTankStats(
|
||||
a: NormalizedTankStats,
|
||||
b: NormalizedTankStats,
|
||||
time?: number,
|
||||
) {
|
||||
const bTanks = Object.keys(b);
|
||||
const changedTanks = bTanks.filter((id) => {
|
||||
return (
|
||||
a[id as unknown as number]?.all.battles !==
|
||||
b[id as unknown as number].all.battles
|
||||
b[id as unknown as number].all.battles &&
|
||||
(time === undefined
|
||||
? true
|
||||
: b[id as unknown as number].last_battle_time > time)
|
||||
);
|
||||
});
|
||||
const diff = changedTanks.map((id) => {
|
||||
@@ -24,7 +31,10 @@ export function deltaTankStats(a: NormalizedTankStats, b: NormalizedTankStats) {
|
||||
in_garage: bTank.in_garage,
|
||||
max_xp: Math.max(aTank.max_xp, bTank.max_xp),
|
||||
in_garage_updated: bTank.in_garage_updated,
|
||||
last_battle_time: bTank.last_battle_time - aTank.last_battle_time,
|
||||
last_battle_time: Math.max(
|
||||
bTank.last_battle_time,
|
||||
aTank.last_battle_time,
|
||||
),
|
||||
mark_of_mastery: bTank.mark_of_mastery,
|
||||
tank_id: bTank.tank_id,
|
||||
|
||||
|
||||
Reference in new issue
Block a user