mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: core chunk 1
This commit is contained in:
1 parent
7447ccc487
commit
e96538bae0
31 files changed
+463
-466
No files matched your search
@@ -0,0 +1,36 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import getWargamingResponse from '../../core/blitz/getWargamingResponse';
|
||||
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 getWargamingResponse<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 getWargamingResponse from '../../core/blitz/getWargamingResponse';
|
||||
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 getWargamingResponse<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 getWargamingResponse from '../../core/blitz/getWargamingResponse';
|
||||
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 getWargamingResponse<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 getWargamingResponse from '../../core/blitz/getWargamingResponse';
|
||||
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 getWargamingResponse<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,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(',');
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { AllStats } from '../blitz/getAccountInfo';
|
||||
|
||||
export interface IndividualPlayerStats {
|
||||
clan: { clan_id: number; name: string; tag: string };
|
||||
statistics: {
|
||||
all: AllStats;
|
||||
wn8: number;
|
||||
wn7: number;
|
||||
average_tier: number;
|
||||
};
|
||||
last_battle_time: number;
|
||||
nickname: string;
|
||||
account_id: number;
|
||||
achievements: {
|
||||
account_id: number;
|
||||
[key: string]: number;
|
||||
};
|
||||
region: Region;
|
||||
}
|
||||
|
||||
export type PlayerStats = IndividualPlayerStats[];
|
||||
|
||||
export async function getPlayerStats<
|
||||
Ids extends number | number[],
|
||||
ReturnType = Ids extends number ? PlayerStats : PlayerStats[],
|
||||
>(region: Region, ids: Ids) {
|
||||
const stats = await Promise.all(
|
||||
((typeof ids === 'number' ? [ids] : ids) as number[]).map((id) =>
|
||||
fetch(`https://www.blitzstars.com/api/playerstats/${id}`).then(
|
||||
(response) => response.json() as Promise<PlayerStats>,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (typeof ids === 'number') return stats[0] as ReturnType;
|
||||
return stats as ReturnType;
|
||||
}
|
||||
@@ -1,7 +1,10 @@
|
||||
import { AllStats } from '../../types/accountInfo';
|
||||
import { AllStats } from '../blitz/getAccountInfo';
|
||||
|
||||
/**
|
||||
* Formula from https://web.archive.org/web/20190105064817/http://wiki.wnefficiency.net/pages/WN8
|
||||
*
|
||||
* @param expected what all players on average perform like
|
||||
* @param average what the player in question performs like
|
||||
*/
|
||||
export default function calculateWN8(expected: AllStats, average: AllStats) {
|
||||
const avgDmg = average.damage_dealt / average.battles;
|
||||
@@ -4,10 +4,7 @@ import {
|
||||
emptyIndividualTankStats,
|
||||
} from '../../types/tanksStats';
|
||||
|
||||
export function diffNormalizedTankStats(
|
||||
a: NormalizedTankStats,
|
||||
b: NormalizedTankStats,
|
||||
) {
|
||||
export function deltaTankStats(a: NormalizedTankStats, b: NormalizedTankStats) {
|
||||
const bTanks = Object.keys(b);
|
||||
const changedTanks = bTanks.filter((id) => {
|
||||
return (
|
||||
@@ -1,11 +1,9 @@
|
||||
// BIG TODO: reorganize code folder
|
||||
|
||||
import { TreeTypeString } from '../../components/Tanks';
|
||||
import { DiffedTankStats } from '../blitzstars/getDiffedTankStats';
|
||||
import { tankAverages } from '../blitzstars/tankAverages';
|
||||
import sumStats from '../../core/blitz/sumStats';
|
||||
import { tankopedia } from '../../core/blitz/tankopedia';
|
||||
import { DiffedTankStats } from '../../core/blitzstars/getDiffedTankStats';
|
||||
import { tankAverages } from '../../core/blitzstars/tankAverages';
|
||||
import calculateWN8 from './calculateWN8';
|
||||
import sumStats from './sumStats';
|
||||
import { tankopedia } from './tankopedia';
|
||||
|
||||
export interface StatFilters {
|
||||
nation?: string;
|
||||
@@ -2,11 +2,11 @@
|
||||
|
||||
import { ContextMenu } from '@radix-ui/themes';
|
||||
import { useEffect, useState } from 'react';
|
||||
import calculateWN8 from '../../../_core/statistics/calculateWN8';
|
||||
import { deltaTankStats } from '../../../_core/statistics/deltaTankStats';
|
||||
import * as Breakdown from '../../../components/Breakdown';
|
||||
import { TreeTypeEnum } from '../../../components/Tanks';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../../constants/wargamingApplicationID';
|
||||
import calculateWN8 from '../../../core/blitz/calculateWN8';
|
||||
import { diffNormalizedTankStats } from '../../../core/blitz/diffNormalizedTankStats';
|
||||
import getWN8Percentile from '../../../core/blitz/getWN8Percentile';
|
||||
import getWargamingResponse from '../../../core/blitz/getWargamingResponse';
|
||||
import { TankopediaEntry, tankopedia } from '../../../core/blitz/tankopedia';
|
||||
@@ -111,7 +111,7 @@ export default function SessionPage() {
|
||||
|
||||
list: (
|
||||
Object.values(
|
||||
diffNormalizedTankStats(session.tankStats, career),
|
||||
deltaTankStats(session.tankStats, career),
|
||||
) as IndividualTankStats[]
|
||||
).map((stats) => {
|
||||
return {
|
||||
|
||||
+87
-91
@@ -1,97 +1,93 @@
|
||||
import { SlashCommandBuilder, escapeMarkdown } from 'discord.js';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import { PlayerHistoriesRaw } from '../core/blitzstars/getPlayerHistories';
|
||||
import getTimeDaysAgo from '../core/blitzstars/getTimeDaysAgo';
|
||||
import addClanChoices from '../core/discord/addClanChoices';
|
||||
import autocompleteClan from '../core/discord/autocompleteClan';
|
||||
import embedWarning from '../core/discord/embedWarning';
|
||||
import resolveClanFromCommand from '../core/discord/resolveClanFromCommand';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { AccountAchievements } from '../types/accountAchievements';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
import { ClanInfo } from '../types/clanInfo';
|
||||
// _____ _____ _ _ _ _ _____ ____ __ __ ______ ____ _____ _ __
|
||||
// |_ _| / ____| | | | /\ | | | | / ____/ __ \| \/ | ____| | _ \ /\ / ____| |/ /
|
||||
// | | | (___ | |__| | / \ | | | | | | | | | | \ / | |__ | |_) | / \ | | | ' /
|
||||
// | | \___ \| __ | / /\ \ | | | | | | | | | | |\/| | __| | _ < / /\ \| | | <
|
||||
// _| |_ ____) | | | |/ ____ \| |____| |____ | |___| |__| | | | | |____ | |_) / ____ \ |____| . \
|
||||
// |_____| |_____/|_| |_/_/ \_\______|______| \_____\____/|_| |_|______| |____/_/ \_\_____|_|\_\
|
||||
|
||||
export const clanEventCommand: CommandRegistry = {
|
||||
inProduction: false,
|
||||
inPublic: true,
|
||||
// import { SlashCommandBuilder, escapeMarkdown } from 'discord.js';
|
||||
// import markdownEscape from 'markdown-escape';
|
||||
// import { getAccountAchievements } from '../_core/blitz/getAccountAchievements';
|
||||
// import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
// import { getClanInfo } from '../_core/blitz/getClanInfo';
|
||||
// import { PlayerHistoriesRaw } from '../core/blitzstars/getPlayerHistories';
|
||||
// import getTimeDaysAgo from '../core/blitzstars/getTimeDaysAgo';
|
||||
// import addClanChoices from '../core/discord/addClanChoices';
|
||||
// import autocompleteClan from '../core/discord/autocompleteClan';
|
||||
// import embedWarning from '../core/discord/embedWarning';
|
||||
// import resolveClanFromCommand from '../core/discord/resolveClanFromCommand';
|
||||
// import { CommandRegistry } from '../events/interactionCreate';
|
||||
|
||||
command: new SlashCommandBuilder()
|
||||
.setName('clan-event')
|
||||
.setDescription('Lists all inactive players')
|
||||
.addStringOption(addClanChoices),
|
||||
// export const clanEventCommand: CommandRegistry = {
|
||||
// inProduction: false,
|
||||
// inPublic: true,
|
||||
|
||||
async handler(interaction) {
|
||||
const { region, id } = await resolveClanFromCommand(interaction);
|
||||
const clan = (
|
||||
await getWargamingResponse<ClanInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/info/?application_id=${WARGAMING_APPLICATION_ID}&clan_id=${id}`,
|
||||
)
|
||||
)[id];
|
||||
const memberIds = clan.members_ids.join(',');
|
||||
const [players, achievements, previousJointVictories] = await Promise.all([
|
||||
getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${memberIds}`,
|
||||
),
|
||||
getWargamingResponse<AccountAchievements>(
|
||||
`https://api.wotblitz.${region}/wotb/account/achievements/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${memberIds}`,
|
||||
),
|
||||
Promise.all(
|
||||
clan.members_ids.map((id) =>
|
||||
fetch(`https://www.blitzstars.com/api/playerstats/${id}`)
|
||||
.then((response) => response.json() as Promise<PlayerHistoriesRaw>)
|
||||
.then((data) => ({
|
||||
id,
|
||||
jointVictory: data[0]?.achievements.jointVictoryCount as
|
||||
| number
|
||||
| undefined,
|
||||
})),
|
||||
),
|
||||
).then((data) =>
|
||||
data.reduce<Record<number, number | undefined>>(
|
||||
(accumulator, value) => ({
|
||||
...accumulator,
|
||||
[value.id]: value.jointVictory,
|
||||
}),
|
||||
{},
|
||||
),
|
||||
),
|
||||
]);
|
||||
const jointVictories = clan.members_ids.map((id) => ({
|
||||
id,
|
||||
joinVictory:
|
||||
players[id].last_battle_time > getTimeDaysAgo(region, 1)
|
||||
? previousJointVictories[id] === undefined
|
||||
? 0
|
||||
: achievements[id].max_series.jointVictory -
|
||||
previousJointVictories[id]!
|
||||
: 0,
|
||||
}));
|
||||
// command: new SlashCommandBuilder()
|
||||
// .setName('clan-event')
|
||||
// .setDescription('Lists all inactive players')
|
||||
// .addStringOption(addClanChoices),
|
||||
|
||||
return [
|
||||
`# ${escapeMarkdown(clan.name)} [${escapeMarkdown(
|
||||
clan.tag,
|
||||
)}]'s platoon wins today: ${(
|
||||
jointVictories.reduce(
|
||||
(accumulator, { joinVictory }) => accumulator + joinVictory,
|
||||
0,
|
||||
) / 2
|
||||
).toFixed(0)}\n${jointVictories
|
||||
.filter(({ joinVictory }) => joinVictory)
|
||||
.sort((a, b) => b.joinVictory - a.joinVictory)
|
||||
.map(
|
||||
({ id, joinVictory }) =>
|
||||
`- ${markdownEscape(players[id].nickname)}: ${joinVictory}`,
|
||||
)
|
||||
.join('\n')}`,
|
||||
// async handler(interaction) {
|
||||
// const { region, id } = await resolveClanFromCommand(interaction);
|
||||
// const clan = await getClanInfo(region, id);
|
||||
// const [players, achievements, previousJointVictories] = await Promise.all([
|
||||
// getAccountInfo(region, clan.members_ids),
|
||||
// getAccountAchievements(region, clan.members_ids),
|
||||
// Promise.all(
|
||||
// clan.members_ids.map((id) =>
|
||||
// fetch(`https://www.blitzstars.com/api/playerstats/${id}`)
|
||||
// .then((response) => response.json() as Promise<PlayerHistoriesRaw>)
|
||||
// .then((data) => ({
|
||||
// id,
|
||||
// jointVictory: data[0]?.achievements.jointVictoryCount as
|
||||
// | number
|
||||
// | undefined,
|
||||
// })),
|
||||
// ),
|
||||
// ).then((data) =>
|
||||
// data.reduce<Record<number, number | undefined>>(
|
||||
// (accumulator, value) => ({
|
||||
// ...accumulator,
|
||||
// [value.id]: value.jointVictory,
|
||||
// }),
|
||||
// {},
|
||||
// ),
|
||||
// ),
|
||||
// ]);
|
||||
// const jointVictories = clan.members_ids.map((id) => ({
|
||||
// id,
|
||||
// joinVictory:
|
||||
// players[id].last_battle_time > getTimeDaysAgo(region, 1)
|
||||
// ? previousJointVictories[id] === undefined
|
||||
// ? 0
|
||||
// : achievements[id].max_series.jointVictory -
|
||||
// previousJointVictories[id]!
|
||||
// : 0,
|
||||
// }));
|
||||
|
||||
embedWarning(
|
||||
'This is an approximation!',
|
||||
"Wargaming provides very little information about platoons publicly. Caveats:\n- Players in two different clans platooning artificially inflates the total count\n- Game-mode battles aren't counted since Wargaming doesn't publicly share that data\n- This command is also subject to Blitzkrieg's reset times (use `/about timezones` for more info)",
|
||||
),
|
||||
];
|
||||
},
|
||||
// return [
|
||||
// `# ${escapeMarkdown(clan.name)} [${escapeMarkdown(
|
||||
// clan.tag,
|
||||
// )}]'s platoon wins today: ${(
|
||||
// jointVictories.reduce(
|
||||
// (accumulator, { joinVictory }) => accumulator + joinVictory,
|
||||
// 0,
|
||||
// ) / 2
|
||||
// ).toFixed(0)}\n${jointVictories
|
||||
// .filter(({ joinVictory }) => joinVictory)
|
||||
// .sort((a, b) => b.joinVictory - a.joinVictory)
|
||||
// .map(
|
||||
// ({ id, joinVictory }) =>
|
||||
// `- ${markdownEscape(players[id].nickname)}: ${joinVictory}`,
|
||||
// )
|
||||
// .join('\n')}`,
|
||||
|
||||
autocomplete: autocompleteClan,
|
||||
};
|
||||
// embedWarning(
|
||||
// 'This is an approximation!',
|
||||
// "Wargaming provides very little information about platoons publicly. Caveats:\n- Players in two different clans platooning artificially inflates the total count\n- Game-mode battles aren't counted since Wargaming doesn't publicly share that data\n- This command is also subject to Blitzkrieg's reset times (use `/about timezones` for more info)",
|
||||
// ),
|
||||
// ];
|
||||
// },
|
||||
|
||||
// autocomplete: autocompleteClan,
|
||||
// };
|
||||
@@ -1,7 +1,6 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import calculateWN8 from '../core/blitz/calculateWN8';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import calculateWN8 from '../_core/statistics/calculateWN8';
|
||||
import sumStats from '../core/blitz/sumStats';
|
||||
import { tankopedia } from '../core/blitz/tankopedia';
|
||||
import getDiffedTankStats from '../core/blitzstars/getDiffedTankStats';
|
||||
@@ -14,7 +13,6 @@ import embedPositive from '../core/discord/embedPositive';
|
||||
import markdownTable, { TableInput } from '../core/discord/markdownTable';
|
||||
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
import { PossiblyPromise } from '../types/possiblyPromise';
|
||||
|
||||
export type SkilledClan = 'SKLLD' | 'SMRI';
|
||||
@@ -48,20 +46,18 @@ export const eligibleCommand: CommandRegistry = {
|
||||
|
||||
async handler(interaction) {
|
||||
const clan = interaction.options.getString('clan') as SkilledClan;
|
||||
const { id, region: server } = await resolvePlayerFromCommand(interaction);
|
||||
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const { id, region: region } = await resolvePlayerFromCommand(interaction);
|
||||
const accountInfo = await getAccountInfo(region, id);
|
||||
const problems: TableInput = [];
|
||||
const title = `${accountInfo[id].nickname}'s eligibility for ${SKILLED_CLANS[clan]}`;
|
||||
const title = `${accountInfo.nickname}'s eligibility for ${SKILLED_CLANS[clan]}`;
|
||||
let isEligible = false;
|
||||
let body = '';
|
||||
|
||||
if (clan === 'SKLLD') {
|
||||
const { diff: diffed } = await getDiffedTankStats(
|
||||
server,
|
||||
region,
|
||||
id,
|
||||
getTimeDaysAgo(server, 30),
|
||||
getTimeDaysAgo(region, 30),
|
||||
getPeriodNow(),
|
||||
);
|
||||
const entries = Object.entries(diffed);
|
||||
@@ -171,7 +167,7 @@ export const eligibleCommand: CommandRegistry = {
|
||||
problems,
|
||||
)}`;
|
||||
} else if (clan === 'SMRI') {
|
||||
const stats = accountInfo[id].statistics.all;
|
||||
const stats = accountInfo.statistics.all;
|
||||
|
||||
if (stats.battles < 1500) {
|
||||
problems.push([
|
||||
|
||||
@@ -2,11 +2,11 @@ import {
|
||||
SlashCommandBuilder,
|
||||
SlashCommandSubcommandGroupBuilder,
|
||||
} from 'discord.js';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import * as Graph from '../components/Graph';
|
||||
import NoData, { NoDataType } from '../components/NoData';
|
||||
import TitleBar from '../components/TitleBar';
|
||||
import Wrapper from '../components/Wrapper';
|
||||
import { getAccountInfo } from '../core/blitz/getAccountInfo';
|
||||
import { getClanLogo } from '../core/blitz/getClanLogo';
|
||||
import { getPlayerClanInfo } from '../core/blitz/getPlayerClanInfo';
|
||||
import resolveTankId from '../core/blitz/resolveTankId';
|
||||
@@ -75,11 +75,7 @@ async function render(
|
||||
|
||||
return (
|
||||
<Wrapper>
|
||||
<TitleBar
|
||||
name={accountInfo[id].nickname}
|
||||
image={logo}
|
||||
description={name}
|
||||
/>
|
||||
<TitleBar name={accountInfo.nickname} image={logo} description={name} />
|
||||
|
||||
{plot.length > 0 && (
|
||||
<Graph.Root
|
||||
@@ -156,9 +152,6 @@ export const evolutionCommand = new Promise<CommandRegistryRaw>(
|
||||
const tankIdRaw = interaction.options.getString('tank')!;
|
||||
const tankId =
|
||||
commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null;
|
||||
const { nickname } = (await getAccountInfo(player.region, player.id))[
|
||||
player.id
|
||||
];
|
||||
const path = interactionToURL(interaction, {
|
||||
...player,
|
||||
...getCustomPeriodParams(interaction),
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import { StatFilters, filterStats } from '../_core/statistics/filterStats';
|
||||
import GenericAllStats from '../components/GenericAllStats';
|
||||
import NoData, { NoDataType } from '../components/NoData';
|
||||
import TierWeights from '../components/TierWeights';
|
||||
import TitleBar from '../components/TitleBar';
|
||||
import Wrapper from '../components/Wrapper';
|
||||
import { StatFilters, filterStats } from '../core/blitz/filterStats';
|
||||
import { getAccountInfo } from '../core/blitz/getAccountInfo';
|
||||
import { getClanLogo } from '../core/blitz/getClanLogo';
|
||||
import { getPlayerClanInfo } from '../core/blitz/getPlayerClanInfo';
|
||||
import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
|
||||
@@ -36,7 +36,7 @@ async function render(
|
||||
{ start, end, name }: ResolvedPeriod,
|
||||
filters: StatFilters,
|
||||
) {
|
||||
const nickname = (await getAccountInfo(region, id))[id].nickname;
|
||||
const { nickname } = await getAccountInfo(region, id);
|
||||
const clan = (await getPlayerClanInfo(region, id))[id]?.clan;
|
||||
const clanImage = clan ? getClanLogo(clan.emblem_set_id) : undefined;
|
||||
const diffedTankStats = await getDiffedTankStats(region, id, start, end);
|
||||
|
||||
+13
-23
@@ -1,16 +1,14 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import { getClanInfo } from '../_core/blitz/getClanInfo';
|
||||
import GenericStats from '../components/GenericStats';
|
||||
import NoData, { NoDataType } from '../components/NoData';
|
||||
import TitleBar from '../components/TitleBar';
|
||||
import Wrapper from '../components/Wrapper';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import addClanChoices from '../core/discord/addClanChoices';
|
||||
import autocompleteClan from '../core/discord/autocompleteClan';
|
||||
import resolveClanFromCommand from '../core/discord/resolveClanFromCommand';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
import { ClanInfo } from '../types/clanInfo';
|
||||
|
||||
const DEFAULT_THRESHOLD = 7;
|
||||
|
||||
@@ -36,24 +34,16 @@ export const inactiveCommand: CommandRegistry = {
|
||||
const threshold =
|
||||
interaction.options.getNumber('threshold')! ?? DEFAULT_THRESHOLD;
|
||||
const time = new Date().getTime() / 1000;
|
||||
const clanData = (
|
||||
await getWargamingResponse<ClanInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/info/?application_id=${WARGAMING_APPLICATION_ID}&clan_id=${id}`,
|
||||
const clanInfo = await getClanInfo(region, id);
|
||||
const accountInfo = await getAccountInfo(region, clanInfo.members_ids);
|
||||
const inactive = accountInfo
|
||||
.map(
|
||||
(account) =>
|
||||
[
|
||||
account.nickname,
|
||||
(time - account.last_battle_time) / 60 / 60 / 24,
|
||||
] as [string, number],
|
||||
)
|
||||
)[id];
|
||||
const memberIds = clanData.members_ids;
|
||||
const accounts = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${memberIds.join(
|
||||
',',
|
||||
)}`,
|
||||
);
|
||||
const inactive = memberIds
|
||||
.map((memberId) => {
|
||||
const member = accounts[memberId];
|
||||
const inactiveDays = (time - member.last_battle_time) / 60 / 60 / 24;
|
||||
|
||||
return [member.nickname, inactiveDays] as [string, number];
|
||||
})
|
||||
.filter(([, inactiveDays]) => inactiveDays >= threshold)
|
||||
.sort((a, b) => b[1] - a[1])
|
||||
.map(
|
||||
@@ -64,8 +54,8 @@ export const inactiveCommand: CommandRegistry = {
|
||||
return (
|
||||
<Wrapper>
|
||||
<TitleBar
|
||||
name={clanData.name}
|
||||
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData.emblem_set_id}.png`}
|
||||
name={clanInfo.name}
|
||||
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanInfo.emblem_set_id}.png`}
|
||||
description={`Inactive for ${threshold}+ Days • ${new Date().toDateString()}`}
|
||||
/>
|
||||
|
||||
|
||||
+33
-80
@@ -1,18 +1,22 @@
|
||||
import { teal } from '@radix-ui/colors';
|
||||
import { AttachmentBuilder, SlashCommandBuilder } from 'discord.js';
|
||||
import {
|
||||
AttachmentBuilder,
|
||||
GuildMemberRoleManager,
|
||||
SlashCommandBuilder,
|
||||
} from 'discord.js';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import discord from '../../discord.json' assert { type: 'json' };
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import { getClanAccountInfo } from '../_core/blitz/getClanAccountInfo';
|
||||
import { Glow } from '../components/AllStatsOverview/components/WN8Display/components/Glow';
|
||||
import Wrapper from '../components/Wrapper';
|
||||
import { REGION_NAMES_SHORT, Region } from '../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import { linkBlitzAndDiscord } from '../core/cockroackdb/discordBlitz';
|
||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||
import embedNegative from '../core/discord/embedNegative';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { theme } from '../stitches.config';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
import { PlayerClanInfo } from '../types/playerClanData';
|
||||
|
||||
const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/;
|
||||
|
||||
@@ -26,86 +30,33 @@ export const verifyCommand: CommandRegistry = {
|
||||
.addStringOption((option) => addUsernameChoices(option).setRequired(true)),
|
||||
|
||||
async handler(interaction) {
|
||||
// const blitzAccount = await resolvePlayerFromCommand(interaction);
|
||||
// const { id, region: server } = blitzAccount;
|
||||
// const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||
// `https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
// );
|
||||
// const clanData = await getWargamingResponse<PlayerClanData>(
|
||||
// `https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||
// );
|
||||
// const clan = clanData[id]?.clan;
|
||||
// const clanTag = clan ? ` [${clan!.tag}]` : '';
|
||||
// const member =
|
||||
// interaction.member &&
|
||||
// interaction.guild?.members.cache.get(interaction.member?.user.id);
|
||||
|
||||
// if (!interaction.guild?.members.me?.permissions.has('ManageNicknames')) {
|
||||
// return embedNegative(
|
||||
// `${markdownEscape(interaction.user.username)} failed to verify`,
|
||||
// "I don't have the permission to change your nickname.",
|
||||
// );
|
||||
// }
|
||||
// if (!interaction.member || !member) {
|
||||
// return embedNegative(
|
||||
// `${interaction.user.username} is not in this server`,
|
||||
// "I couldn't find this person in this server. Did they leave?",
|
||||
// );
|
||||
// }
|
||||
|
||||
// try {
|
||||
// await member.setNickname(`${accountInfo[id].nickname}${clanTag}`);
|
||||
|
||||
// if (interaction.guildId === discord.sklld_guild_id) {
|
||||
// if (!interaction.guild?.members.me?.permissions.has('ManageRoles')) {
|
||||
// return embedNegative(
|
||||
// `${markdownEscape(interaction.user.username)} failed to verify`,
|
||||
// "I don't have the permission to change your manage roles.",
|
||||
// );
|
||||
// }
|
||||
|
||||
// await member.roles.remove(discord.sklld_verify_role);
|
||||
// await member.roles.add(discord.sklld_peasant_role);
|
||||
// }
|
||||
|
||||
// return embedPositive(
|
||||
// `${interaction.user.username} is verified`,
|
||||
// `The user is now verified as ${markdownEscape(
|
||||
// accountInfo[id].nickname,
|
||||
// )}${markdownEscape(clanTag)}`,
|
||||
// );
|
||||
// } catch (error) {
|
||||
// return embedNegative(
|
||||
// `${interaction.user.username} failed to verify`,
|
||||
// "I can't change your nickname because you have higher permissions than me. Try setting your nickname to your Blitz username manually.",
|
||||
// );
|
||||
// }
|
||||
|
||||
const username = interaction.options.getString('username', true);
|
||||
|
||||
if (serverAndIdPattern.test(username)) {
|
||||
const [region, idString] = username.split('/');
|
||||
const id = parseInt(idString);
|
||||
const discordId = parseInt(interaction.user.id);
|
||||
// const account = (
|
||||
// await getWargamingResponse<AccountInfo>(
|
||||
// `https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
// )
|
||||
// )[id];
|
||||
// const clan = await getWargamingResponse<PlayerClanData>(
|
||||
// `https://api.wotblitz.${region}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||
// );
|
||||
const [account, clan] = await Promise.all([
|
||||
getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
),
|
||||
getWargamingResponse<PlayerClanInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||
),
|
||||
]);
|
||||
const accountInfo = await getAccountInfo(region as Region, id);
|
||||
const clanAccountInfo = await getClanAccountInfo(region as Region, id);
|
||||
|
||||
await linkBlitzAndDiscord(discordId, region as Region, id);
|
||||
|
||||
if (interaction.guildId === discord.sklld_guild_id) {
|
||||
if (!interaction.guild?.members.me?.permissions.has('ManageRoles')) {
|
||||
return embedNegative(
|
||||
`${markdownEscape(interaction.user.username)} failed to verify`,
|
||||
"I don't have the permission to change your manage roles.",
|
||||
);
|
||||
}
|
||||
|
||||
await (interaction.member!.roles as GuildMemberRoleManager).remove(
|
||||
discord.sklld_verify_role,
|
||||
);
|
||||
await (interaction.member!.roles as GuildMemberRoleManager).add(
|
||||
discord.sklld_peasant_role,
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Wrapper fat>
|
||||
<div
|
||||
@@ -205,7 +156,7 @@ export const verifyCommand: CommandRegistry = {
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
{clan[id]?.clan ? (
|
||||
{clanAccountInfo?.clan ? (
|
||||
<img
|
||||
style={{
|
||||
width: 64,
|
||||
@@ -213,7 +164,7 @@ export const verifyCommand: CommandRegistry = {
|
||||
borderRadius: 32,
|
||||
objectFit: 'cover',
|
||||
}}
|
||||
src={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clan[id]?.clan?.emblem_set_id}.png`}
|
||||
src={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanAccountInfo?.clan?.emblem_set_id}.png`}
|
||||
/>
|
||||
) : null}
|
||||
<div
|
||||
@@ -234,7 +185,7 @@ export const verifyCommand: CommandRegistry = {
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{account[id].nickname}
|
||||
{accountInfo.nickname}
|
||||
</span>
|
||||
<span
|
||||
style={{
|
||||
@@ -242,7 +193,9 @@ export const verifyCommand: CommandRegistry = {
|
||||
color: theme.colors.textLowContrast,
|
||||
}}
|
||||
>
|
||||
{clan[id]?.clan ? `[${clan[id]?.clan?.tag}] - ` : ''}
|
||||
{clanAccountInfo?.clan
|
||||
? `[${clanAccountInfo?.clan?.tag}] - `
|
||||
: ''}
|
||||
{REGION_NAMES_SHORT[region as Region]}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import { getClanAccountInfo } from '../_core/blitz/getClanAccountInfo';
|
||||
import NoData, { NoDataType } from '../components/NoData';
|
||||
import * as Tanks from '../components/Tanks';
|
||||
import TitleBar from '../components/TitleBar';
|
||||
import Wrapper from '../components/Wrapper';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import { getClanLogo } from '../core/blitz/getClanLogo';
|
||||
import getTankStats from '../core/blitz/getTankStats';
|
||||
import getTreeType from '../core/blitz/getTreeType';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import resolveTankName from '../core/blitz/resolveTankName';
|
||||
import {
|
||||
TIER_ROMAN_NUMERALS,
|
||||
@@ -20,29 +21,6 @@ import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
import { PlayerClanInfo } from '../types/playerClanData';
|
||||
|
||||
const COMP_TANKS = [
|
||||
// light tanks
|
||||
24321, // t-100 lt
|
||||
20257, // sheridan
|
||||
3649, // bat chat
|
||||
19537, // vickers
|
||||
|
||||
// heavy tanks
|
||||
6145, // is-4
|
||||
7169, // is-7
|
||||
10785, // t110e5
|
||||
12161, // strvk
|
||||
4481, // kranvagn
|
||||
22817, // m6 yoh
|
||||
6225, // fv215b
|
||||
5425, // wz 113
|
||||
7297, // 60tp
|
||||
58641, // vk 72
|
||||
6753, // type 71
|
||||
];
|
||||
|
||||
export const ownedTanksCommand: CommandRegistry = {
|
||||
inProduction: true,
|
||||
@@ -58,9 +36,7 @@ export const ownedTanksCommand: CommandRegistry = {
|
||||
const tier = Number(interaction.options.getString('tier'));
|
||||
const account = await resolvePlayerFromCommand(interaction);
|
||||
const { id, region: server } = account;
|
||||
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const accountInfo = await getAccountInfo(server, id);
|
||||
const tankStats = await getTankStats(server, id);
|
||||
const filteredTanks = (
|
||||
await Promise.all(
|
||||
@@ -70,9 +46,7 @@ export const ownedTanksCommand: CommandRegistry = {
|
||||
})),
|
||||
)
|
||||
).filter((tank) => tank.tankopedia?.tier === tier);
|
||||
const clanData = await getWargamingResponse<PlayerClanInfo>(
|
||||
`https://api.wotblitz.${server}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||
);
|
||||
const clanAccountInfo = await getClanAccountInfo(server, id);
|
||||
const groupedTanks: Record<string, TankopediaEntry[]> = {};
|
||||
const nations: string[] = [];
|
||||
|
||||
@@ -90,10 +64,10 @@ export const ownedTanksCommand: CommandRegistry = {
|
||||
return (
|
||||
<Wrapper>
|
||||
<TitleBar
|
||||
name={accountInfo[id].nickname}
|
||||
name={accountInfo.nickname}
|
||||
image={
|
||||
clanData[id]?.clan
|
||||
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData[id]?.clan?.emblem_set_id}.png`
|
||||
clanAccountInfo?.clan
|
||||
? getClanLogo(clanAccountInfo.clan.emblem_set_id)
|
||||
: undefined
|
||||
}
|
||||
description={`Tier ${TIER_ROMAN_NUMERALS[tier as Tier]} tanks`}
|
||||
|
||||
@@ -1,16 +1,14 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { startCase } from 'lodash';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import { getAccountAchievements } from '../_core/blitz/getAccountAchievements';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||
import embedInfo from '../core/discord/embedInfo';
|
||||
import markdownTable, { TableInputEntry } from '../core/discord/markdownTable';
|
||||
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { AccountAchievements } from '../types/accountAchievements';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
|
||||
type SortBy = 'name' | 'count';
|
||||
|
||||
@@ -35,22 +33,17 @@ export const playerAchievementsCommand: CommandRegistry = {
|
||||
async handler(interaction) {
|
||||
const sortBy = (interaction.options.getString('sort') ?? 'name') as SortBy;
|
||||
const account = await resolvePlayerFromCommand(interaction);
|
||||
const { id, region: server } = account;
|
||||
const accounts = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const accountsAchievements =
|
||||
await getWargamingResponse<AccountAchievements>(
|
||||
`https://api.wotblitz.${server}/wotb/account/achievements/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const accountAchievements = accountsAchievements[id];
|
||||
const { id, region: region } = account;
|
||||
const accountInfo = await getAccountInfo(region, id);
|
||||
const accountsAchievements = await getAccountAchievements(region, id);
|
||||
const accountAchievements = accountsAchievements;
|
||||
const compound = {
|
||||
...accountAchievements.achievements,
|
||||
...accountAchievements.max_series,
|
||||
};
|
||||
|
||||
return embedInfo(
|
||||
`${markdownEscape(accounts[id].nickname)}'s information`,
|
||||
`${markdownEscape(accountInfo.nickname)}'s information`,
|
||||
|
||||
markdownTable(
|
||||
Object.keys(compound)
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import markdownEscape from 'markdown-escape';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||
import embedInfo from '../core/discord/embedInfo';
|
||||
import markdownTable from '../core/discord/markdownTable';
|
||||
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
|
||||
export const playerInfoCommand: CommandRegistry = {
|
||||
inProduction: true,
|
||||
@@ -21,11 +19,8 @@ export const playerInfoCommand: CommandRegistry = {
|
||||
|
||||
async handler(interaction) {
|
||||
const account = await resolvePlayerFromCommand(interaction);
|
||||
const { id, region: server } = account;
|
||||
const accounts = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const accountInfo = accounts[id];
|
||||
const { id, region: region } = account;
|
||||
const accountInfo = await getAccountInfo(region, id);
|
||||
|
||||
return embedInfo(
|
||||
`${markdownEscape(accountInfo.nickname)}'s information`,
|
||||
|
||||
+13
-20
@@ -5,14 +5,14 @@ import {
|
||||
SlashCommandSubcommandGroupBuilder,
|
||||
} from 'discord.js';
|
||||
import { BlitzkriegRatingsLeaderboard } from '../../scripts/buildRatingsLeaderboard';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import { getClanAccountInfo } from '../_core/blitz/getClanAccountInfo';
|
||||
import * as Leaderboard from '../components/Leaderboard';
|
||||
import TitleBar from '../components/TitleBar';
|
||||
import Wrapper from '../components/Wrapper';
|
||||
import { REGION_NAMES_SHORT, Region } from '../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../constants/wargamingApplicationID';
|
||||
import getArchivedRatingsInfo from '../core/blitz/getArchivedRatingsInfo';
|
||||
import getRatingsInfo from '../core/blitz/getRatingsInfo';
|
||||
import getWargamingResponse from '../core/blitz/getWargamingResponse';
|
||||
import regionToRegionSubdomain from '../core/blitz/regionToRegionSubdomain';
|
||||
import getMidnightLeaderboard, {
|
||||
DATABASE_REPO,
|
||||
@@ -25,8 +25,6 @@ import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||
import { octokit } from '../core/github/octokit';
|
||||
import throwError from '../core/node/throwError';
|
||||
import { CommandRegistryRaw } from '../events/interactionCreate';
|
||||
import { AccountInfo } from '../types/accountInfo';
|
||||
import { PlayerClanInfo } from '../types/playerClanData';
|
||||
|
||||
export interface RatingsPlayer {
|
||||
spa_id: number;
|
||||
@@ -312,9 +310,9 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
||||
firstPlayerIndex,
|
||||
lastPlayerIndex + 1,
|
||||
);
|
||||
const ids = trimmed.map((player) => player.id).join(',');
|
||||
const clanData = await getWargamingResponse<PlayerClanInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${ids}&extra=clan`,
|
||||
const clanData = await getClanAccountInfo(
|
||||
region,
|
||||
trimmed.map(({ id }) => id),
|
||||
);
|
||||
|
||||
return trimmed.map(
|
||||
@@ -373,14 +371,8 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
||||
|
||||
if (regionRatingsInfo.detail !== undefined) return noOngoingSeason;
|
||||
|
||||
const accountInfo = await getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
const clan = (
|
||||
await getWargamingResponse<PlayerClanInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}&extra=clan`,
|
||||
)
|
||||
)[id]?.clan;
|
||||
const accountInfo = await getAccountInfo(region, id);
|
||||
const clan = (await getClanAccountInfo(region, id, ['clan']))?.clan;
|
||||
const regionSubdomain = regionToRegionSubdomain(region);
|
||||
const neighbors =
|
||||
subcommandGroup === 'current'
|
||||
@@ -426,7 +418,7 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
||||
|
||||
if (playerIndex === -1) {
|
||||
throw throwError(
|
||||
`${accountInfo[id].nickname} didn't player ratings in season ${season}`,
|
||||
`${accountInfo.nickname} didn't player ratings in season ${season}`,
|
||||
'This player did not participate in this season or did not get past calibration.',
|
||||
);
|
||||
}
|
||||
@@ -436,9 +428,10 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
||||
playerIndex - halfRange,
|
||||
playerIndex + halfRange + 1,
|
||||
);
|
||||
const ids = trimmed.map((player) => player.id).join(',');
|
||||
const clanData = await getWargamingResponse<PlayerClanInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/clans/accountinfo/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${ids}&extra=clan`,
|
||||
const clanData = await getClanAccountInfo(
|
||||
region,
|
||||
trimmed.map((player) => player.id),
|
||||
['clan'],
|
||||
);
|
||||
|
||||
return trimmed.map((player, index) => ({
|
||||
@@ -464,7 +457,7 @@ export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
||||
? `https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clan.emblem_set_id}.png`
|
||||
: undefined;
|
||||
titleName = neighbors
|
||||
? accountInfo[id].nickname
|
||||
? accountInfo.nickname
|
||||
: `No Ongoing Season - ${REGION_NAMES_SHORT[region]}`;
|
||||
titleDescription = 'Ratings neighbours';
|
||||
playersBefore = neighbors ? neighbors[0].position - 1 : 0;
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import { SlashCommandBuilder } from 'discord.js';
|
||||
import { getAccountInfo } from '../_core/blitz/getAccountInfo';
|
||||
import { StatFilters, filterStats } from '../_core/statistics/filterStats';
|
||||
import AllStatsOverview from '../components/AllStatsOverview';
|
||||
import NoData, { NoDataType } from '../components/NoData';
|
||||
import TitleBar from '../components/TitleBar';
|
||||
import Wrapper from '../components/Wrapper';
|
||||
import { StatFilters, filterStats } from '../core/blitz/filterStats';
|
||||
import { getAccountInfo } from '../core/blitz/getAccountInfo';
|
||||
import { getClanLogo } from '../core/blitz/getClanLogo';
|
||||
import { getPlayerClanInfo } from '../core/blitz/getPlayerClanInfo';
|
||||
import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import { AccountInfo } from '../../types/accountInfo';
|
||||
import getWargamingResponse from './getWargamingResponse';
|
||||
|
||||
// BIG TODO: generalize all get wargaming calls
|
||||
export function getAccountInfo(region: Region, id: number) {
|
||||
return getWargamingResponse<AccountInfo>(
|
||||
`https://api.wotblitz.${region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
import { StatFilters } from '../../_core/statistics/filterStats';
|
||||
import { TREE_TYPE_NAMES } from '../../components/Tanks';
|
||||
import { StatFilters } from '../blitz/filterStats';
|
||||
import resolveTankName from '../blitz/resolveTankName';
|
||||
import { TIER_ROMAN_NUMERALS, Tier, tankopediaInfo } from '../blitz/tankopedia';
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Region } from '../../constants/regions';
|
||||
import { WARGAMING_APPLICATION_ID } from '../../constants/wargamingApplicationID';
|
||||
import { AccountInfo, AllStats } from '../../types/accountInfo';
|
||||
import { AccountInfo } from '../../types/accountInfo';
|
||||
import {
|
||||
GetHistoriesOptions,
|
||||
Histories,
|
||||
@@ -10,26 +10,6 @@ import {
|
||||
import getWargamingResponse from '../blitz/getWargamingResponse';
|
||||
import { emptyAllStats } from './getDiffedTankStats';
|
||||
|
||||
export interface PlayerHistoryRaw {
|
||||
clan: { clan_id: number; name: string; tag: string };
|
||||
statistics: {
|
||||
all: AllStats;
|
||||
wn8: number;
|
||||
wn7: number;
|
||||
average_tier: number;
|
||||
};
|
||||
last_battle_time: number;
|
||||
nickname: string;
|
||||
account_id: number;
|
||||
achievements: {
|
||||
account_id: number;
|
||||
[key: string]: number;
|
||||
};
|
||||
region: Region;
|
||||
}
|
||||
|
||||
export type PlayerHistoriesRaw = PlayerHistoryRaw[];
|
||||
|
||||
export default async function getPlayerHistories(
|
||||
server: Region,
|
||||
id: number,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ButtonInteraction } from 'discord.js';
|
||||
import { StatFilters } from '../../_core/statistics/filterStats';
|
||||
import { TreeTypeString } from '../../components/Tanks';
|
||||
import { StatFilters } from '../blitz/filterStats';
|
||||
|
||||
export function getFiltersFromButton(interaction: ButtonInteraction) {
|
||||
const url = new URL(`https://example.com/${interaction.customId}`);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { ChatInputCommandInteraction } from 'discord.js';
|
||||
import { StatFilters } from '../../_core/statistics/filterStats';
|
||||
import { TreeTypeString } from '../../components/Tanks';
|
||||
import { StatFilters } from '../blitz/filterStats';
|
||||
|
||||
export function getFiltersFromCommand(
|
||||
interaction: ChatInputCommandInteraction,
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
export interface AccountAchievements {
|
||||
[id: number]: {
|
||||
achievements: {
|
||||
[achievement: string]: number;
|
||||
};
|
||||
max_series: {
|
||||
[achievement: string]: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
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;
|
||||
}
|
||||
|
||||
export interface AccountInfo {
|
||||
[accountId: number]: {
|
||||
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;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,30 +0,0 @@
|
||||
export interface ClanInfo {
|
||||
[clanId: number]: {
|
||||
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;
|
||||
};
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
export type PlayerClanInfo = {
|
||||
[accountId: number]: {
|
||||
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;
|
||||
};
|
||||
Reference in new issue
Block a user