feat: added basic infrastructure for ratings command

This commit is contained in:
TresAbhi committed 2023-07-15 18:44:20 +00:00
1 parent 9419aec116
commit aa6011b18d
40 files changed
+227 -96

No files matched your search

+1 -1
View File
@@ -49,7 +49,7 @@ export const eligibleCommand: CommandRegistry = {
async handler(interaction) {
const clan = interaction.options.getString('clan') as SkilledClan;
const { id, server } = await resolvePlayerFromCommand(interaction);
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}`,
);
+3 -3
View File
@@ -34,7 +34,7 @@ export const evolutionCommand: CommandRegistry = {
true,
) as StatType;
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.server, interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const tankIdRaw = interaction.options.getString('tank')!;
const tankId =
commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null;
@@ -42,7 +42,7 @@ export const evolutionCommand: CommandRegistry = {
const end = interaction.options.getInteger('end');
const { nickname } = (
await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${player.server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
`https://api.wotblitz.${player.region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
)
)[player.id];
const path = interactionToURL(interaction, {
@@ -57,7 +57,7 @@ export const evolutionCommand: CommandRegistry = {
primaryButton(path, 'Refresh'),
// linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.server}/${nickname}${
`https://www.blitzstars.com/player/${player.region}/${nickname}${
commandGroup === 'tank' ? `/tank/${tankId!}` : ''
}`,
'BlitzStars',
+3 -3
View File
@@ -33,7 +33,7 @@ export const fullStatsCommand: CommandRegistry = {
true,
) as StatType;
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.server, interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const tankIdRaw = interaction.options.getString('tank')!;
const tankId =
commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null;
@@ -47,7 +47,7 @@ export const fullStatsCommand: CommandRegistry = {
});
const { nickname } = (
await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${player.server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
`https://api.wotblitz.${player.region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
)
)[player.id];
@@ -56,7 +56,7 @@ export const fullStatsCommand: CommandRegistry = {
primaryButton(path, 'Refresh'),
// linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.server}/${nickname}`,
`https://www.blitzstars.com/player/${player.region}/${nickname}`,
'BlitzStars',
),
];
+2 -2
View File
@@ -4,7 +4,7 @@ import NoData, { NoDataType } from '../components/NoData';
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
import TitleBar from '../components/TitleBar';
import Wrapper from '../components/Wrapper';
import { REGION_DOMAIN_NAMES } from '../constants/regions';
import { REGION_NAMES } from '../constants/regions';
import getBlitzClan from '../core/blitz/getBlitzClan';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import addClanChoices from '../core/discord/addClanChoices';
@@ -72,7 +72,7 @@ export const inactiveCommand: CommandRegistry = {
nameDiscriminator="(Inactivity)"
image={`https://wotblitz-gc.gcdn.co/icons/clanEmblems1x/clan-icon-v2-${clanData.emblem_set_id}.png`}
description={`${threshold}+ Days • ${new Date().toDateString()} • ${
REGION_DOMAIN_NAMES[server]
REGION_NAMES[server]
}`}
/>
+3 -3
View File
@@ -4,7 +4,7 @@ import PoweredBy, { PoweredByType } from '../components/PoweredBy';
import * as Tanks from '../components/Tanks';
import TitleBar from '../components/TitleBar';
import Wrapper from '../components/Wrapper';
import { REGION_DOMAIN_NAMES } from '../constants/regions';
import { REGION_NAMES } from '../constants/regions';
import getTankStats from '../core/blitz/getTankStats';
import getTreeType from '../core/blitz/getTreeType';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
@@ -74,7 +74,7 @@ export const ownedTanksCommand: CommandRegistry = {
async handler(interaction) {
const tier = Number(interaction.options.getString('tier'));
const account = await resolvePlayerFromCommand(interaction);
const { id, server } = account;
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}`,
);
@@ -105,7 +105,7 @@ export const ownedTanksCommand: CommandRegistry = {
: undefined
}
description={`Owned tanks • ${new Date().toDateString()} • ${
REGION_DOMAIN_NAMES[server]
REGION_NAMES[server]
}`}
/>
+1 -1
View File
@@ -36,7 +36,7 @@ export const playerAchievementsCommand: CommandRegistry = {
async handler(interaction) {
const sortBy = (interaction.options.getString('sort') ?? 'name') as SortBy;
const account = await resolvePlayerFromCommand(interaction);
const { id, server } = account;
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}`,
);
+1 -1
View File
@@ -22,7 +22,7 @@ export const playerInfoCommand: CommandRegistry = {
async handler(interaction) {
const account = await resolvePlayerFromCommand(interaction);
const { id, server } = account;
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}`,
);
+115
View File
@@ -0,0 +1,115 @@
import { SlashCommandBuilder, SlashCommandSubcommandBuilder } from 'discord.js';
import regionToRegionSubdomain from '../core/blitz/regionToRegionSubdomain';
import addUsernameChoices from '../core/discord/addUsernameChoices';
import autocompleteUsername from '../core/discord/autocompleteUsername';
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
import { CommandRegistry } from '../events/interactionCreate';
export interface LeaguePlayer {
spa_id: number;
mmr: number;
season_number: number;
calibrationBattlesLeft: number;
number: number;
percentile: number;
skip: boolean;
updated_at: string;
score: number;
nickname: string;
clan_tag: string;
}
export interface LeagueTop {
result: LeaguePlayer[];
}
const LEAGUE_INDEXES = ['diamond', 'platinum', 'gold', 'silver', 'bronze'];
function optionalParameters(option: SlashCommandSubcommandBuilder) {
return option
.addIntegerOption((option) =>
option
.setName('limit')
.setDescription('How many rows to display (default: 16)')
.setRequired(true)
.setMinValue(5)
.setMaxValue(30),
)
.addStringOption(addUsernameChoices);
}
export const ratingsCommand: CommandRegistry = {
inProduction: true,
inDevelopment: true,
inPublic: true,
inPreview: true,
command: new SlashCommandBuilder()
.setName('ratings')
.setDescription('Ratings battles statistics')
.addSubcommandGroup((option) =>
option
.setName('league')
.setDescription('Top league players')
.addSubcommand((option) =>
optionalParameters(
option
.setName('diamond')
.setDescription('Top Diamond League players'),
),
)
.addSubcommand((option) =>
optionalParameters(
option
.setName('platinum')
.setDescription('Top Platinum League players'),
),
)
.addSubcommand((option) =>
optionalParameters(
option.setName('gold').setDescription('Top Gold League players'),
),
)
.addSubcommand((option) =>
optionalParameters(
option
.setName('silver')
.setDescription('Top Silver League players'),
),
)
.addSubcommand((option) =>
optionalParameters(
option
.setName('bronze')
.setDescription('Top Bronze League players'),
),
),
),
async handler(interaction) {
const subcommandGroup = interaction.options.getSubcommandGroup(true);
if (subcommandGroup === 'league') {
const limit = interaction.options.getInteger('limit') ?? 16;
const subcommand = interaction.options.getSubcommand(true);
const leagueIndex = LEAGUE_INDEXES.indexOf(subcommand);
const player = await resolvePlayerFromCommand(interaction);
const regionSubdomain = regionToRegionSubdomain(player.region);
const { result } = await fetch(
`https://${regionSubdomain}.wotblitz.com/en/api/rating-leaderboards/league/${leagueIndex}/top/`,
).then((response) => response.json() as Promise<LeagueTop>);
return `\`\`\`${result
.slice(0, limit)
.map(
(player) =>
`${player.number}: ${player.nickname} [${player.clan_tag}]`,
)
.join('\n')}\`\`\``;
}
return [];
},
autocomplete: autocompleteUsername,
};
+3 -5
View File
@@ -1,6 +1,6 @@
import { SlashCommandBuilder } from 'discord.js';
import markdownEscape from 'markdown-escape';
import { REGION_DOMAIN_NAMES, RegionDomain } from '../constants/regions';
import { REGION_NAMES, Region } from '../constants/regions';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import addClanChoices from '../core/discord/addClanChoices';
import addServerChoices from '../core/discord/addServerChoices';
@@ -28,7 +28,7 @@ export const searchClansCommand: CommandRegistry = {
),
async handler(interaction) {
const server = interaction.options.getString('server') as RegionDomain;
const server = interaction.options.getString('server') as Region;
const clan = interaction.options.getString('clan')!;
const limit = interaction.options.getInteger('limit') ?? 25;
const clanList = await getWargamingResponse<ClanList>(
@@ -36,9 +36,7 @@ export const searchClansCommand: CommandRegistry = {
);
return embedInfo(
`Clan search for "${markdownEscape(clan)}" in ${
REGION_DOMAIN_NAMES[server]
}`,
`Clan search for "${markdownEscape(clan)}" in ${REGION_NAMES[server]}`,
clanList.length === 0
? 'No clans found.'
: `\`\`\`\n${clanList
+3 -5
View File
@@ -1,6 +1,6 @@
import { SlashCommandBuilder } from 'discord.js';
import markdownEscape from 'markdown-escape';
import { REGION_DOMAIN_NAMES, RegionDomain } from '../constants/regions';
import { REGION_NAMES, Region } from '../constants/regions';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import { usernamePattern } from '../core/blitz/listPlayers';
import addServerChoices from '../core/discord/addServerChoices';
@@ -31,7 +31,7 @@ export const searchPlayersCommand: CommandRegistry = {
),
async handler(interaction) {
const server = interaction.options.getString('server') as RegionDomain;
const server = interaction.options.getString('server') as Region;
const name = interaction.options.getString('username')!;
const limit = interaction.options.getInteger('limit') ?? 25;
const trimmedSearch = name.trim();
@@ -44,9 +44,7 @@ export const searchPlayersCommand: CommandRegistry = {
: [];
return embedInfo(
`Player search for "${markdownEscape(name)}" in ${
REGION_DOMAIN_NAMES[server]
}`,
`Player search for "${markdownEscape(name)}" in ${REGION_NAMES[server]}`,
`\`\`\`${
players.length === 0
? 'No players found.'
+4 -4
View File
@@ -26,7 +26,7 @@ export const statsCommand: CommandRegistry = {
command: addStatTypeSubCommandGroups(
new SlashCommandBuilder()
.setName('stats')
.setDescription('In-game statistics'),
.setDescription('Regular battles statistics'),
),
async handler(interaction) {
@@ -34,7 +34,7 @@ export const statsCommand: CommandRegistry = {
true,
) as StatType;
const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.server, interaction);
const period = resolvePeriodFromCommand(player.region, interaction);
const tankIdRaw = interaction.options.getString('tank')!;
const tankId =
commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null;
@@ -48,7 +48,7 @@ export const statsCommand: CommandRegistry = {
});
const { nickname } = (
await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${player.server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
`https://api.wotblitz.${player.region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
)
)[player.id];
@@ -57,7 +57,7 @@ export const statsCommand: CommandRegistry = {
primaryButton(path, 'Refresh'),
linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.server}/${nickname}`,
`https://www.blitzstars.com/player/${player.region}/${nickname}`,
'BlitzStars',
),
];
+2 -2
View File
@@ -37,7 +37,7 @@ export const todayCommand: CommandRegistry = {
const limit = interaction.options.getInteger('limit') ?? Infinity;
const { nickname } = (
await getWargamingResponse<AccountInfo>(
`https://api.wotblitz.${player.server}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
`https://api.wotblitz.${player.region}/wotb/account/info/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${player.id}`,
)
)[player.id];
const path = interactionToURL(interaction, player);
@@ -47,7 +47,7 @@ export const todayCommand: CommandRegistry = {
primaryButton(path, 'Refresh'),
linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton(
`https://www.blitzstars.com/player/${player.server}/${nickname}`,
`https://www.blitzstars.com/player/${player.region}/${nickname}`,
'BlitzStars',
),
];
+1 -1
View File
@@ -24,7 +24,7 @@ export const verifyCommand: CommandRegistry = {
async handler(interaction) {
const blitzAccount = await resolvePlayerFromCommand(interaction);
const { id, server } = blitzAccount;
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}`,
);
+2 -2
View File
@@ -1,7 +1,7 @@
export type RegionDomain = 'com' | 'eu' | 'asia';
export type Region = 'com' | 'eu' | 'asia';
export type RegionSubdomain = 'na' | 'eu' | 'asia';
export const REGION_DOMAIN_NAMES: Record<RegionDomain, string> = {
export const REGION_NAMES: Record<Region, string> = {
com: 'North America',
eu: 'Europe',
asia: 'Asia',
+2 -2
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import { serverAndIdPattern } from '../discord/resolvePlayerFromCommand';
import throwError from '../node/throwError';
import listClans from './listClans';
@@ -6,7 +6,7 @@ import listClans from './listClans';
export default async function getBlitzClan(clan: string) {
if (serverAndIdPattern.test(clan)) {
const [server, accountId] = clan.split('/');
return { server: server as RegionDomain, id: Number(accountId) };
return { server: server as Region, id: Number(accountId) };
} else {
const accounts = await listClans(clan);
+3 -3
View File
@@ -1,10 +1,10 @@
import { REGION_DOMAIN_NAMES, RegionDomain } from '../../constants/regions';
import { REGION_NAMES, Region } from '../../constants/regions';
import { TanksStats } from '../../types/tanksStats';
import { WARGAMING_APPLICATION_ID } from '../node/arguments';
import throwError from '../node/throwError';
import getWargamingResponse from './getWargamingResponse';
export default async function getTankStats(server: RegionDomain, id: number) {
export default async function getTankStats(server: Region, id: number) {
const tankStats = await getWargamingResponse<TanksStats>(
`https://api.wotblitz.${server}/wotb/tanks/stats/?application_id=${WARGAMING_APPLICATION_ID}&account_id=${id}`,
);
@@ -12,7 +12,7 @@ export default async function getTankStats(server: RegionDomain, id: number) {
if (tankStats[id] === null) {
throw throwError(
'No tank stats available',
`Wargaming says there is no tank stats for this account. This account may not have any battles/tanks or exist in the ${REGION_DOMAIN_NAMES[server]} server.`,
`Wargaming says there is no tank stats for this account. This account may not have any battles/tanks or exist in the ${REGION_NAMES[server]} server.`,
);
}
+4 -4
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import { Clan, ClanList } from '../../types/clanList';
import { WARGAMING_APPLICATION_ID } from '../node/arguments';
import getWargamingResponse from './getWargamingResponse';
@@ -21,7 +21,7 @@ export default async function listClans(search: string, limit = 9) {
value &&
value.map((account) => ({
...account,
server: 'com' as RegionDomain,
server: 'com' as Region,
})),
),
getWargamingResponse<ClanList>(
@@ -31,7 +31,7 @@ export default async function listClans(search: string, limit = 9) {
value &&
value.map((account) => ({
...account,
server: 'eu' as RegionDomain,
server: 'eu' as Region,
})),
),
getWargamingResponse<ClanList>(
@@ -41,7 +41,7 @@ export default async function listClans(search: string, limit = 9) {
value &&
value.map((account) => ({
...account,
server: 'asia' as RegionDomain,
server: 'asia' as Region,
})),
),
])
+4 -4
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import { Account, AccountList } from '../../types/accountList';
import { WARGAMING_APPLICATION_ID } from '../node/arguments';
import getWargamingResponse from './getWargamingResponse';
@@ -25,7 +25,7 @@ export default async function listPlayers(search: string, limit = 9) {
value &&
value.map((account) => ({
...account,
server: 'com' as RegionDomain,
server: 'com' as Region,
})),
),
getWargamingResponse<AccountList>(
@@ -35,7 +35,7 @@ export default async function listPlayers(search: string, limit = 9) {
value &&
value.map((account) => ({
...account,
server: 'eu' as RegionDomain,
server: 'eu' as Region,
})),
),
getWargamingResponse<AccountList>(
@@ -45,7 +45,7 @@ export default async function listPlayers(search: string, limit = 9) {
value &&
value.map((account) => ({
...account,
server: 'asia' as RegionDomain,
server: 'asia' as Region,
})),
),
])
@@ -0,0 +1,7 @@
import { Region, RegionSubdomain } from '../../constants/regions';
export default function regionToRegionSubdomain(
regionDomain: Region,
): RegionSubdomain {
return regionDomain === 'com' ? 'na' : regionDomain;
}
+2 -2
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import { AllStats } from '../../types/accountInfo';
import getTankHistories, {
TankHistories,
@@ -35,7 +35,7 @@ export const emptyTankHistoryNode: TankHistoryRaw = {
};
export default async function getDiffedTankStats(
server: RegionDomain,
server: Region,
id: number,
start: number,
end: number,
+2 -2
View File
@@ -1,9 +1,9 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import { Period } from '../discord/addPeriodSubCommands';
import getTimeDaysAgo from './getTimeDaysAgo';
export default function getPeriodStart(
server: RegionDomain,
server: Region,
period: Exclude<Period, 'custom'>,
) {
if (period === 'career') {
+3 -3
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import { AccountInfo, AllStats } from '../../types/accountInfo';
import {
GetHistoriesOptions,
@@ -25,13 +25,13 @@ export interface PlayerHistoryRaw {
account_id: number;
[key: string]: number;
};
region: RegionDomain;
region: Region;
}
export type PlayerHistoriesRaw = PlayerHistoryRaw[];
export default async function getPlayerHistories(
server: RegionDomain,
server: Region,
id: number,
options?: Partial<GetHistoriesOptions>,
) {
+2 -2
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import {
GetHistoriesOptions,
Histories,
@@ -32,7 +32,7 @@ export const getTankHistoriesDefaultOptions: GetTankHistoriesOptions = {
};
export default async function getTankHistories(
server: RegionDomain,
server: Region,
id: number,
options?: Partial<GetTankHistoriesOptions>,
) {
+3 -3
View File
@@ -1,12 +1,12 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
export const TIME_ZONE_MAPPINGS: Record<RegionDomain, number> = {
export const TIME_ZONE_MAPPINGS: Record<Region, number> = {
com: -5, // Central North American Time
eu: +1, // Central European Time
asia: +7, // Central Asia Standard Time
};
export default function getTimeDaysAgo(server: RegionDomain, daysAgo: number) {
export default function getTimeDaysAgo(server: Region, daysAgo: number) {
const now = new Date();
if (daysAgo === 0) now.getTime() / 1000;
+4 -4
View File
@@ -1,14 +1,14 @@
import { SlashCommandStringOption } from 'discord.js';
import { REGION_DOMAIN_NAMES } from '../../constants/regions';
import { REGION_NAMES } from '../../constants/regions';
export default function addServerChoices(option: SlashCommandStringOption) {
return option
.setName('server')
.setDescription('The Blitz server you are in')
.addChoices(
{ name: REGION_DOMAIN_NAMES.com, value: 'com' },
{ name: REGION_DOMAIN_NAMES.eu, value: 'eu' },
{ name: REGION_DOMAIN_NAMES.asia, value: 'asia' },
{ name: REGION_NAMES.com, value: 'com' },
{ name: REGION_NAMES.eu, value: 'eu' },
{ name: REGION_NAMES.asia, value: 'asia' },
)
.setRequired(true);
}
+2 -2
View File
@@ -3,7 +3,7 @@ import {
AutocompleteInteraction,
CacheType,
} from 'discord.js';
import { REGION_DOMAIN_NAMES } from '../../constants/regions';
import { REGION_NAMES } from '../../constants/regions';
import listClans from '../blitz/listClans';
export default async function autocompleteClan(
@@ -18,7 +18,7 @@ export default async function autocompleteClan(
? players.map(
(player) =>
({
name: `${player.name} (${REGION_DOMAIN_NAMES[player.server]})`,
name: `${player.name} (${REGION_NAMES[player.server]})`,
value: `${player.server}/${player.clan_id}`,
}) satisfies ApplicationCommandOptionChoiceData<string>,
)
+2 -4
View File
@@ -3,7 +3,7 @@ import {
AutocompleteInteraction,
CacheType,
} from 'discord.js';
import { REGION_DOMAIN_NAMES } from '../../constants/regions';
import { REGION_NAMES } from '../../constants/regions';
import listPlayers from '../blitz/listPlayers';
export default async function autocompleteUsername(
@@ -19,9 +19,7 @@ export default async function autocompleteUsername(
? players.map(
(player) =>
({
name: `${player.nickname} (${
REGION_DOMAIN_NAMES[player.server]
})`,
name: `${player.nickname} (${REGION_NAMES[player.server]})`,
value: `${player.server}/${player.account_id}`,
}) satisfies ApplicationCommandOptionChoiceData<string>,
)
+2 -2
View File
@@ -1,10 +1,10 @@
import { ButtonInteraction, CacheType } from 'discord.js';
import { CYCLIC_API } from '../../constants/cyclic';
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import resolvePeriodFromURL from '../express/resolvePeriodFromURL';
export default function resolvePeriodFromButton(
server: RegionDomain,
server: Region,
interaction: ButtonInteraction<CacheType>,
) {
return resolvePeriodFromURL(server, `${CYCLIC_API}/${interaction.customId}`);
+2 -2
View File
@@ -1,5 +1,5 @@
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import getPeriodNow from '../blitzstars/getPeriodNow';
import getPeriodStart from '../blitzstars/getPeriodStart';
import getTimeDaysAgo from '../blitzstars/getTimeDaysAgo';
@@ -31,7 +31,7 @@ export interface ResolvedPeriod {
}
export default function resolvePeriodFromCommand(
server: RegionDomain,
server: Region,
interaction: ChatInputCommandInteraction<CacheType>,
) {
let statsName: string;
+4 -4
View File
@@ -1,5 +1,5 @@
import { CacheType, ChatInputCommandInteraction } from 'discord.js';
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import listPlayers, {
usernamePatternWithoutPosition,
} from '../blitz/listPlayers';
@@ -8,7 +8,7 @@ import throwError from '../node/throwError';
export const serverAndIdPattern = /(com|eu|asia)\/[0-9]+/;
export interface ResolvedPlayer {
server: RegionDomain;
region: Region;
id: number;
}
@@ -31,7 +31,7 @@ export default async function resolvePlayerFromCommand(
if (serverAndIdPattern.test(username)) {
const [server, accountId] = username.split('/');
return {
server: server as RegionDomain,
region: server as Region,
id: Number(accountId),
} satisfies ResolvedPlayer;
} else {
@@ -39,7 +39,7 @@ export default async function resolvePlayerFromCommand(
if (accounts[0]) {
return {
server: accounts[0].server,
region: accounts[0].server,
id: accounts[0].account_id,
} satisfies ResolvedPlayer;
} else {
+2 -2
View File
@@ -1,10 +1,10 @@
import { Request } from 'express';
import { CYCLIC_API } from '../../constants/cyclic';
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import resolvePeriodFromURL from './resolvePeriodFromURL';
export default function resolvePeriodFromRequest(
server: RegionDomain,
server: Region,
request: Request,
) {
return resolvePeriodFromURL(server, `${CYCLIC_API}${request.path}`);
+2 -2
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import getPeriodNow from '../blitzstars/getPeriodNow';
import getPeriodStart from '../blitzstars/getPeriodStart';
import getTimeDaysAgo from '../blitzstars/getTimeDaysAgo';
@@ -10,7 +10,7 @@ import {
} from '../discord/resolvePeriodFromCommand';
export default function resolvePeriodFromURL(
server: RegionDomain,
server: Region,
urlString: string,
) {
let statsName: string;
+2 -2
View File
@@ -1,4 +1,4 @@
import { RegionDomain } from '../../constants/regions';
import { Region } from '../../constants/regions';
import { ResolvedPlayer } from '../discord/resolvePlayerFromCommand';
export default function resolvePlayerFromURL(urlString: string) {
@@ -6,6 +6,6 @@ export default function resolvePlayerFromURL(urlString: string) {
return {
id: parseInt(url.searchParams.get('id')!),
server: url.searchParams.get('server') as RegionDomain,
region: url.searchParams.get('server') as Region,
} satisfies ResolvedPlayer;
}
@@ -6,6 +6,7 @@ import {
ChatInputCommandInteraction,
} from 'discord.js';
import { commands } from '..';
import discord from '../../../../discord.json' assert { type: 'json' };
import embedNegative from '../../../core/discord/embedNegative';
import embedWarning from '../../../core/discord/embedWarning';
import normalizeInteractionReturnable from '../../../core/discord/normalizeInteractionReturnable';
@@ -21,6 +22,19 @@ export default async function handleChatInputCommand(
await interaction.deferReply();
try {
if (registry.inPreview && interaction.guildId !== discord.tres_guild_id) {
interaction.editReply({
embeds: [
embedWarning(
`\`/${registry.command.name}\` is in Public Preview`,
'[Join the official Discord server](https://discord.gg/nDt7AjGJQH) to gain early access to this command before it is released to the public.',
),
],
});
return;
}
const returnable = await registry.handler(interaction);
if (registry.handlesInteraction) return;
+3
View File
@@ -23,6 +23,7 @@ import { ownedTanksCommand } from '../../commands/ownedTanks';
import { pingCommand } from '../../commands/ping';
import { playerAchievementsCommand } from '../../commands/playerAchievements';
import { playerInfoCommand } from '../../commands/playerInfo';
import { ratingsCommand } from '../../commands/ratings';
import { searchClansCommand } from '../../commands/searchClans';
import { searchPlayersCommand } from '../../commands/searchPlayers';
import { searchTanksCommand } from '../../commands/searchTanks';
@@ -56,6 +57,7 @@ export interface Registry {
export interface CommandRegistry<HandlesInteraction extends boolean = boolean>
extends Registry {
inPublic: boolean;
inPreview?: boolean;
handlesInteraction?: HandlesInteraction;
command:
| SlashCommandBuilder
@@ -88,6 +90,7 @@ export const COMMANDS_RAW: CommandRegistry[] = [
pingCommand,
evolutionCommand,
statsCommand,
ratingsCommand,
];
export const commands: Record<string, CommandRegistry> = COMMANDS_RAW.reduce(
(accumulator, registry) => {
+3 -3
View File
@@ -3,7 +3,7 @@ import NoData, { NoDataType } from '../components/NoData';
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
import TitleBar from '../components/TitleBar';
import Wrapper from '../components/Wrapper';
import { REGION_DOMAIN_NAMES } from '../constants/regions';
import { REGION_NAMES } from '../constants/regions';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import resolveTankName from '../core/blitz/resolveTankName';
import { tankopedia } from '../core/blitz/tankopedia';
@@ -20,7 +20,7 @@ import { StatType } from './fullStats';
export default async function evolution<Type extends StatType>(
type: Type,
{ start, end, evolutionName }: ResolvedPeriod,
{ server, id }: ResolvedPlayer,
{ region: server, id }: ResolvedPlayer,
tankId: Type extends 'tank' ? number : null,
) {
let nameDiscriminator: string | undefined;
@@ -89,7 +89,7 @@ export default async function evolution<Type extends StatType>(
nameDiscriminator={nameDiscriminator}
image={image}
description={`${evolutionName} • ${new Date().toDateString()} • ${
REGION_DOMAIN_NAMES[server]
REGION_NAMES[server]
}`}
/>
+3 -3
View File
@@ -4,7 +4,7 @@ import PoweredBy, { PoweredByType } from '../components/PoweredBy';
import TierWeights, { TierWeightsRecord } from '../components/TierWeights';
import TitleBar from '../components/TitleBar';
import Wrapper from '../components/Wrapper';
import { REGION_DOMAIN_NAMES } from '../constants/regions';
import { REGION_NAMES } from '../constants/regions';
import calculateWN8 from '../core/blitz/calculateWN8';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import resolveTankName from '../core/blitz/resolveTankName';
@@ -28,7 +28,7 @@ export type StatType = 'player' | 'tank';
export default async function fullStats<Type extends StatType>(
type: Type,
{ start, end, statsName }: ResolvedPeriod,
{ server, id }: ResolvedPlayer,
{ region: server, id }: ResolvedPlayer,
tankId: Type extends 'tank' ? number : null,
) {
let nameDiscriminator: string | undefined;
@@ -143,7 +143,7 @@ export default async function fullStats<Type extends StatType>(
nameDiscriminator={nameDiscriminator}
image={image}
description={`${statsName} • ${new Date().toDateString()} • ${
REGION_DOMAIN_NAMES[server]
REGION_NAMES[server]
}`}
/>
+3 -3
View File
@@ -4,7 +4,7 @@ import PoweredBy, { PoweredByType } from '../components/PoweredBy';
import { TierWeightsRecord } from '../components/TierWeights';
import TitleBar from '../components/TitleBar';
import Wrapper from '../components/Wrapper';
import { REGION_DOMAIN_NAMES } from '../constants/regions';
import { REGION_NAMES } from '../constants/regions';
import calculateWN8 from '../core/blitz/calculateWN8';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
import resolveTankName from '../core/blitz/resolveTankName';
@@ -29,7 +29,7 @@ export type StatType = 'player' | 'tank';
export default async function stats<Type extends StatType>(
type: Type,
{ start, end, statsName }: ResolvedPeriod,
{ server, id }: ResolvedPlayer,
{ region: server, id }: ResolvedPlayer,
tankId: Type extends 'tank' ? number : null,
naked = false,
) {
@@ -164,7 +164,7 @@ export default async function stats<Type extends StatType>(
nameDiscriminator={nameDiscriminator}
image={image}
description={`${statsName} • ${new Date().toDateString()} • ${
REGION_DOMAIN_NAMES[server]
REGION_NAMES[server]
}`}
/>
+3 -3
View File
@@ -3,7 +3,7 @@ import NoData, { NoDataType } from '../components/NoData';
import PoweredBy, { PoweredByType } from '../components/PoweredBy';
import TitleBar from '../components/TitleBar';
import Wrapper from '../components/Wrapper';
import { REGION_DOMAIN_NAMES } from '../constants/regions';
import { REGION_NAMES } from '../constants/regions';
import calculateWN8 from '../core/blitz/calculateWN8';
import getTankStats from '../core/blitz/getTankStats';
import getWargamingResponse from '../core/blitz/getWargamingResponse';
@@ -21,7 +21,7 @@ import { PlayerClanData } from '../types/playerClanData';
import { PossiblyPromise } from '../types/possiblyPromise';
export default async function today(
{ server, id }: ResolvedPlayer,
{ region: server, id }: ResolvedPlayer,
limit = Infinity,
naked?: boolean,
) {
@@ -162,7 +162,7 @@ export default async function today(
: undefined
}
description={`Today's breakdown • ${new Date().toDateString()} • ${
REGION_DOMAIN_NAMES[server]
REGION_NAMES[server]
}`}
/>