mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: /today alias for /breakdown today
This commit is contained in:
1 parent
0480445bae
commit
23a23e36bb
14 files changed
+252
-153
No files matched your search
Vendored
+1
@@ -39,6 +39,7 @@
|
|||||||
"ownedtanks",
|
"ownedtanks",
|
||||||
"playerachievements",
|
"playerachievements",
|
||||||
"playerinfo",
|
"playerinfo",
|
||||||
|
"Promisable",
|
||||||
"ratingsleaderboard",
|
"ratingsleaderboard",
|
||||||
"ratingsplot",
|
"ratingsplot",
|
||||||
"researchable",
|
"researchable",
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
|
|||||||
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
||||||
import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod';
|
import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod';
|
||||||
import { tankAverages } from '../core/blitzstars/tankAverages';
|
import { tankAverages } from '../core/blitzstars/tankAverages';
|
||||||
import addFilterOptions from '../core/discord/addFilterOptions';
|
import addPeriodicFilterOptions from '../core/discord/addPeriodicFilterOptions';
|
||||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||||
import autocompleteTanks from '../core/discord/autocompleteTanks';
|
import autocompleteTanks from '../core/discord/autocompleteTanks';
|
||||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||||
@@ -33,12 +33,12 @@ import resolvePlayerFromCommand, {
|
|||||||
import calculateWN8 from '../core/statistics/calculateWN8';
|
import calculateWN8 from '../core/statistics/calculateWN8';
|
||||||
import { StatFilters, filterStats } from '../core/statistics/filterStats';
|
import { StatFilters, filterStats } from '../core/statistics/filterStats';
|
||||||
import getWN8Percentile from '../core/statistics/getWN8Percentile';
|
import getWN8Percentile from '../core/statistics/getWN8Percentile';
|
||||||
import { CommandRegistryRaw } from '../events/interactionCreate';
|
import { CommandRegistryPromisable } from '../events/interactionCreate';
|
||||||
|
|
||||||
const ROWS_PER_PAGE = 8;
|
const ROWS_PER_PAGE = 8;
|
||||||
const MAX_PAGES = 10;
|
const MAX_PAGES = 10;
|
||||||
|
|
||||||
async function render(
|
export async function renderBreakdown(
|
||||||
{ region, id }: ResolvedPlayer,
|
{ region, id }: ResolvedPlayer,
|
||||||
{ start, end, name }: ResolvedPeriod,
|
{ start, end, name }: ResolvedPeriod,
|
||||||
filters: StatFilters,
|
filters: StatFilters,
|
||||||
@@ -290,9 +290,9 @@ async function render(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const breakdownCommand = new Promise<CommandRegistryRaw>(
|
export const breakdownCommand = new Promise<CommandRegistryPromisable>(
|
||||||
async (resolve) => {
|
async (resolve) => {
|
||||||
const command = await addFilterOptions(
|
const command = await addPeriodicFilterOptions(
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('breakdown')
|
.setName('breakdown')
|
||||||
.setDescription("A period's breakdown by tanks played"),
|
.setDescription("A period's breakdown by tanks played"),
|
||||||
@@ -316,7 +316,7 @@ export const breakdownCommand = new Promise<CommandRegistryRaw>(
|
|||||||
});
|
});
|
||||||
|
|
||||||
return [
|
return [
|
||||||
...(await render(player, period, filters)),
|
...(await renderBreakdown(player, period, filters)),
|
||||||
buttonPrimary(path, 'Refresh'),
|
buttonPrimary(path, 'Refresh'),
|
||||||
await getBlitzStarsLinkButton(player.region, player.id),
|
await getBlitzStarsLinkButton(player.region, player.id),
|
||||||
];
|
];
|
||||||
@@ -332,7 +332,7 @@ export const breakdownCommand = new Promise<CommandRegistryRaw>(
|
|||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
const period = resolvePeriodFromButton(player.region, interaction);
|
||||||
const filters = getFiltersFromButton(interaction);
|
const filters = getFiltersFromButton(interaction);
|
||||||
|
|
||||||
return await render(player, period, filters);
|
return await renderBreakdown(player, period, filters);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ export const debugCommand: CommandRegistry = {
|
|||||||
.setName('debug')
|
.setName('debug')
|
||||||
.setDescription('Debug information about the bot'),
|
.setDescription('Debug information about the bot'),
|
||||||
|
|
||||||
async handler(interaction) {
|
async handler() {
|
||||||
const currentTime = new Date().getTime();
|
const currentTime = new Date().getTime();
|
||||||
const uptime = currentTime - executionStart;
|
const uptime = currentTime - executionStart;
|
||||||
const list = [
|
const list = [
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ import resolvePlayerFromButton from '../core/discord/resolvePlayerFromButton';
|
|||||||
import resolvePlayerFromCommand, {
|
import resolvePlayerFromCommand, {
|
||||||
ResolvedPlayer,
|
ResolvedPlayer,
|
||||||
} from '../core/discord/resolvePlayerFromCommand';
|
} from '../core/discord/resolvePlayerFromCommand';
|
||||||
import { CommandRegistryRaw } from '../events/interactionCreate';
|
import { CommandRegistryPromisable } from '../events/interactionCreate';
|
||||||
|
|
||||||
type EvolutionStatType = 'player' | 'tank';
|
type EvolutionStatType = 'player' | 'tank';
|
||||||
|
|
||||||
@@ -107,7 +107,7 @@ async function render(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const evolutionCommand = new Promise<CommandRegistryRaw>(
|
export const evolutionCommand = new Promise<CommandRegistryPromisable>(
|
||||||
async (resolve) => {
|
async (resolve) => {
|
||||||
let playerGroup: SlashCommandSubcommandGroupBuilder;
|
let playerGroup: SlashCommandSubcommandGroupBuilder;
|
||||||
let tankGroup: SlashCommandSubcommandGroupBuilder;
|
let tankGroup: SlashCommandSubcommandGroupBuilder;
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { emblemIdToURL } from '../core/blitzkrieg/emblemIdToURL';
|
|||||||
import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
|
import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
|
||||||
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
||||||
import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod';
|
import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod';
|
||||||
import addFilterOptions from '../core/discord/addFilterOptions';
|
import addPeriodicFilterOptions from '../core/discord/addPeriodicFilterOptions';
|
||||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||||
import autocompleteTanks from '../core/discord/autocompleteTanks';
|
import autocompleteTanks from '../core/discord/autocompleteTanks';
|
||||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||||
@@ -29,7 +29,7 @@ import resolvePlayerFromCommand, {
|
|||||||
} from '../core/discord/resolvePlayerFromCommand';
|
} from '../core/discord/resolvePlayerFromCommand';
|
||||||
import { StatFilters, filterStats } from '../core/statistics/filterStats';
|
import { StatFilters, filterStats } from '../core/statistics/filterStats';
|
||||||
import { getTierWeights } from '../core/statistics/getTierWeights';
|
import { getTierWeights } from '../core/statistics/getTierWeights';
|
||||||
import { CommandRegistryRaw } from '../events/interactionCreate';
|
import { CommandRegistryPromisable } from '../events/interactionCreate';
|
||||||
|
|
||||||
async function render(
|
async function render(
|
||||||
{ region, id }: ResolvedPlayer,
|
{ region, id }: ResolvedPlayer,
|
||||||
@@ -64,9 +64,9 @@ async function render(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const fullStatsCommand = new Promise<CommandRegistryRaw>(
|
export const fullStatsCommand = new Promise<CommandRegistryPromisable>(
|
||||||
async (resolve) => {
|
async (resolve) => {
|
||||||
const command = await addFilterOptions(
|
const command = await addPeriodicFilterOptions(
|
||||||
new SlashCommandBuilder()
|
new SlashCommandBuilder()
|
||||||
.setName('full-stats')
|
.setName('full-stats')
|
||||||
.setDescription('Full in-game statistics'),
|
.setDescription('Full in-game statistics'),
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import addRegionChoices from '../core/discord/addRegionChoices';
|
|||||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||||
import embedNegative from '../core/discord/embedNegative';
|
import embedNegative from '../core/discord/embedNegative';
|
||||||
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||||
import { CommandRegistryRaw } from '../events/interactionCreate';
|
import { CommandRegistryPromisable } from '../events/interactionCreate';
|
||||||
|
|
||||||
export interface RatingsPlayer {
|
export interface RatingsPlayer {
|
||||||
spa_id: number;
|
spa_id: number;
|
||||||
@@ -120,7 +120,7 @@ const noOngoingSeason = embedNegative(
|
|||||||
"Wargaming didn't provide any data for this season.",
|
"Wargaming didn't provide any data for this season.",
|
||||||
);
|
);
|
||||||
|
|
||||||
export const ratingsCommand = new Promise<CommandRegistryRaw>(
|
export const ratingsCommand = new Promise<CommandRegistryPromisable>(
|
||||||
async (resolve) => {
|
async (resolve) => {
|
||||||
const latestArchivedSeasonNumber = await getArchivedLatestSeasonNumber();
|
const latestArchivedSeasonNumber = await getArchivedLatestSeasonNumber();
|
||||||
const onGoingSeason = await isOnGoingRatingsSeason();
|
const onGoingSeason = await isOnGoingRatingsSeason();
|
||||||
|
|||||||
+42
-40
@@ -9,7 +9,7 @@ import { emblemIdToURL } from '../core/blitzkrieg/emblemIdToURL';
|
|||||||
import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
|
import { filtersToDescription } from '../core/blitzkrieg/filtersToDescription';
|
||||||
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
||||||
import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod';
|
import getStatsInPeriod from '../core/blitzstars/getStatsInPeriod';
|
||||||
import addFilterOptions from '../core/discord/addFilterOptions';
|
import addPeriodicFilterOptions from '../core/discord/addPeriodicFilterOptions';
|
||||||
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||||
import autocompleteTanks from '../core/discord/autocompleteTanks';
|
import autocompleteTanks from '../core/discord/autocompleteTanks';
|
||||||
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||||
@@ -27,7 +27,7 @@ import resolvePlayerFromCommand, {
|
|||||||
ResolvedPlayer,
|
ResolvedPlayer,
|
||||||
} from '../core/discord/resolvePlayerFromCommand';
|
} from '../core/discord/resolvePlayerFromCommand';
|
||||||
import { StatFilters, filterStats } from '../core/statistics/filterStats';
|
import { StatFilters, filterStats } from '../core/statistics/filterStats';
|
||||||
import { CommandRegistryRaw } from '../events/interactionCreate';
|
import { CommandRegistryPromisable } from '../events/interactionCreate';
|
||||||
|
|
||||||
async function render(
|
async function render(
|
||||||
{ region, id }: ResolvedPlayer,
|
{ region, id }: ResolvedPlayer,
|
||||||
@@ -57,48 +57,50 @@ async function render(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
|
export const statsCommand = new Promise<CommandRegistryPromisable>(
|
||||||
const command = await addFilterOptions(
|
async (resolve) => {
|
||||||
new SlashCommandBuilder()
|
const command = await addPeriodicFilterOptions(
|
||||||
.setName('stats')
|
new SlashCommandBuilder()
|
||||||
.setDescription('Regular battles statistics'),
|
.setName('stats')
|
||||||
(option) => option.addStringOption(addUsernameChoices),
|
.setDescription('Regular battles statistics'),
|
||||||
);
|
(option) => option.addStringOption(addUsernameChoices),
|
||||||
|
);
|
||||||
|
|
||||||
resolve({
|
resolve({
|
||||||
inProduction: true,
|
inProduction: true,
|
||||||
inPublic: true,
|
inPublic: true,
|
||||||
|
|
||||||
command,
|
command,
|
||||||
|
|
||||||
async handler(interaction) {
|
async handler(interaction) {
|
||||||
const player = await resolvePlayerFromCommand(interaction);
|
const player = await resolvePlayerFromCommand(interaction);
|
||||||
const period = resolvePeriodFromCommand(player.region, interaction);
|
const period = resolvePeriodFromCommand(player.region, interaction);
|
||||||
const filters = await getFiltersFromCommand(interaction);
|
const filters = await getFiltersFromCommand(interaction);
|
||||||
const path = commandToURL(interaction, {
|
const path = commandToURL(interaction, {
|
||||||
...player,
|
...player,
|
||||||
...getCustomPeriodParams(interaction),
|
...getCustomPeriodParams(interaction),
|
||||||
...filters,
|
...filters,
|
||||||
});
|
});
|
||||||
|
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
render(player, period, filters),
|
render(player, period, filters),
|
||||||
buttonRefresh(interaction, path),
|
buttonRefresh(interaction, path),
|
||||||
getBlitzStarsLinkButton(player.region, player.id),
|
getBlitzStarsLinkButton(player.region, player.id),
|
||||||
]);
|
]);
|
||||||
},
|
},
|
||||||
|
|
||||||
autocomplete: (interaction) => {
|
autocomplete: (interaction) => {
|
||||||
autocompleteUsername(interaction);
|
autocompleteUsername(interaction);
|
||||||
autocompleteTanks(interaction);
|
autocompleteTanks(interaction);
|
||||||
},
|
},
|
||||||
|
|
||||||
async button(interaction) {
|
async button(interaction) {
|
||||||
const player = await resolvePlayerFromButton(interaction);
|
const player = await resolvePlayerFromButton(interaction);
|
||||||
const period = resolvePeriodFromButton(player.region, interaction);
|
const period = resolvePeriodFromButton(player.region, interaction);
|
||||||
const filters = getFiltersFromButton(interaction);
|
const filters = getFiltersFromButton(interaction);
|
||||||
|
|
||||||
return await render(player, period, filters);
|
return await render(player, period, filters);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
},
|
||||||
|
);
|
||||||
@@ -0,0 +1,71 @@
|
|||||||
|
import { SlashCommandBuilder } from 'discord.js';
|
||||||
|
import { encyclopediaInfo } from '../core/blitz/encyclopediaInfo';
|
||||||
|
import { getBlitzStarsLinkButton } from '../core/blitzstars/getBlitzStarsLinkButton';
|
||||||
|
import { addFilterOptions } from '../core/discord/addFilterOptions';
|
||||||
|
import addUsernameChoices from '../core/discord/addUsernameChoices';
|
||||||
|
import autocompleteTanks from '../core/discord/autocompleteTanks';
|
||||||
|
import autocompleteUsername from '../core/discord/autocompleteUsername';
|
||||||
|
import buttonPrimary from '../core/discord/buttonPrimary';
|
||||||
|
import commandToURL from '../core/discord/commandToURL';
|
||||||
|
import { getCustomPeriodParams } from '../core/discord/getCustomPeriodParams';
|
||||||
|
import { getFiltersFromButton } from '../core/discord/getFiltersFromButton';
|
||||||
|
import { getFiltersFromCommand } from '../core/discord/getFiltersFromCommand';
|
||||||
|
import resolvePeriodFromButton from '../core/discord/resolvePeriodFromButton';
|
||||||
|
import resolvePeriodFromCommand from '../core/discord/resolvePeriodFromCommand';
|
||||||
|
import resolvePlayerFromButton from '../core/discord/resolvePlayerFromButton';
|
||||||
|
import resolvePlayerFromCommand from '../core/discord/resolvePlayerFromCommand';
|
||||||
|
import { CommandRegistryPromisable } from '../events/interactionCreate';
|
||||||
|
import { renderBreakdown } from './breakdown';
|
||||||
|
|
||||||
|
export const todayCommand = new Promise<CommandRegistryPromisable>(
|
||||||
|
async (resolve) => {
|
||||||
|
const awaitedEncyclopediaInfo = await encyclopediaInfo;
|
||||||
|
const command = addFilterOptions(
|
||||||
|
new SlashCommandBuilder()
|
||||||
|
.setName('today')
|
||||||
|
.setDescription("Today's played tanks and statistics"),
|
||||||
|
awaitedEncyclopediaInfo,
|
||||||
|
).addStringOption(addUsernameChoices);
|
||||||
|
|
||||||
|
resolve({
|
||||||
|
inProduction: true,
|
||||||
|
inPublic: true,
|
||||||
|
|
||||||
|
command,
|
||||||
|
|
||||||
|
async handler(interaction) {
|
||||||
|
const player = await resolvePlayerFromCommand(interaction);
|
||||||
|
const period = resolvePeriodFromCommand(
|
||||||
|
player.region,
|
||||||
|
interaction,
|
||||||
|
'today',
|
||||||
|
);
|
||||||
|
const filters = await getFiltersFromCommand(interaction);
|
||||||
|
const path = commandToURL(interaction, {
|
||||||
|
...player,
|
||||||
|
...getCustomPeriodParams(interaction, true),
|
||||||
|
...filters,
|
||||||
|
});
|
||||||
|
|
||||||
|
return [
|
||||||
|
...(await renderBreakdown(player, period, filters)),
|
||||||
|
buttonPrimary(path, 'Refresh'),
|
||||||
|
await getBlitzStarsLinkButton(player.region, player.id),
|
||||||
|
];
|
||||||
|
},
|
||||||
|
|
||||||
|
autocomplete: (interaction) => {
|
||||||
|
autocompleteUsername(interaction);
|
||||||
|
autocompleteTanks(interaction);
|
||||||
|
},
|
||||||
|
|
||||||
|
async button(interaction) {
|
||||||
|
const player = await resolvePlayerFromButton(interaction);
|
||||||
|
const period = resolvePeriodFromButton(player.region, interaction);
|
||||||
|
const filters = getFiltersFromButton(interaction);
|
||||||
|
|
||||||
|
return await renderBreakdown(player, period, filters);
|
||||||
|
},
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
@@ -1,76 +1,60 @@
|
|||||||
import {
|
import { SlashCommandBuilder, SlashCommandSubcommandBuilder } from 'discord.js';
|
||||||
SlashCommandBuilder,
|
|
||||||
SlashCommandSubcommandBuilder,
|
|
||||||
SlashCommandSubcommandGroupBuilder,
|
|
||||||
} from 'discord.js';
|
|
||||||
import { TREE_TYPE_NAMES, TreeTypeString } from '../../components/Tanks';
|
import { TREE_TYPE_NAMES, TreeTypeString } from '../../components/Tanks';
|
||||||
import { encyclopediaInfo } from '../blitz/encyclopediaInfo';
|
import { EncyclopediaInfo } from '../blitz/encyclopediaInfo';
|
||||||
import addPeriodSubCommands from './addPeriodSubCommands';
|
|
||||||
import addTankChoices from './addTankChoices';
|
import addTankChoices from './addTankChoices';
|
||||||
import addTierChoices from './addTierChoices';
|
import addTierChoices from './addTierChoices';
|
||||||
|
|
||||||
export default async function addFilterOptions<
|
export function addFilterOptions<
|
||||||
OptionType extends SlashCommandBuilder | SlashCommandSubcommandGroupBuilder,
|
Option extends SlashCommandBuilder | SlashCommandSubcommandBuilder,
|
||||||
>(
|
>(option: Option, encyclopediaInfo: EncyclopediaInfo) {
|
||||||
option: OptionType,
|
return option
|
||||||
extra: (
|
.addStringOption((option) =>
|
||||||
option: SlashCommandSubcommandBuilder,
|
option
|
||||||
) => SlashCommandSubcommandBuilder = (option) => option,
|
.setName('nation')
|
||||||
): Promise<OptionType> {
|
.setDescription('Nation')
|
||||||
const awaitedEncyclopediaInfo = await encyclopediaInfo;
|
.addChoices(
|
||||||
|
...Object.entries(encyclopediaInfo.vehicle_nations).map(
|
||||||
addPeriodSubCommands(option, (option) => {
|
([type, name]) => ({ name, value: type }),
|
||||||
extra(option);
|
),
|
||||||
|
)
|
||||||
return option
|
.setRequired(false),
|
||||||
.addStringOption((option) =>
|
)
|
||||||
option
|
.addStringOption((option) => addTierChoices(option).setRequired(false))
|
||||||
.setName('nation')
|
.addStringOption((option) =>
|
||||||
.setDescription('Nation')
|
option
|
||||||
.addChoices(
|
.setName('tank-type')
|
||||||
...Object.entries(awaitedEncyclopediaInfo.vehicle_nations).map(
|
.setDescription('Tank type')
|
||||||
([type, name]) => ({ name, value: type }),
|
.addChoices(
|
||||||
),
|
...Object.entries(encyclopediaInfo.vehicle_types).map(
|
||||||
)
|
([type, name]) => ({
|
||||||
.setRequired(false),
|
name: name.replace(' Tank', ''),
|
||||||
)
|
value: type,
|
||||||
.addStringOption((option) => addTierChoices(option).setRequired(false))
|
}),
|
||||||
.addStringOption((option) =>
|
),
|
||||||
option
|
)
|
||||||
.setName('tank-type')
|
.setRequired(false),
|
||||||
.setDescription('Tank type')
|
)
|
||||||
.addChoices(
|
.addStringOption((option) =>
|
||||||
...Object.entries(awaitedEncyclopediaInfo.vehicle_types).map(
|
option
|
||||||
([type, name]) => ({
|
.setName('tree-type')
|
||||||
name: name.replace(' Tank', ''),
|
.setDescription('Tech tree type')
|
||||||
value: type,
|
.addChoices(
|
||||||
}),
|
{
|
||||||
),
|
name: TREE_TYPE_NAMES['researchable'],
|
||||||
)
|
value: 'researchable' satisfies TreeTypeString,
|
||||||
.setRequired(false),
|
},
|
||||||
)
|
{
|
||||||
.addStringOption((option) =>
|
name: TREE_TYPE_NAMES.premium,
|
||||||
option
|
value: 'premium' satisfies TreeTypeString,
|
||||||
.setName('tree-type')
|
},
|
||||||
.setDescription('Tech tree type')
|
{
|
||||||
.addChoices(
|
name: TREE_TYPE_NAMES.collector,
|
||||||
{
|
value: 'collector' satisfies TreeTypeString,
|
||||||
name: TREE_TYPE_NAMES['researchable'],
|
},
|
||||||
value: 'researchable' satisfies TreeTypeString,
|
)
|
||||||
},
|
.setRequired(false),
|
||||||
{
|
)
|
||||||
name: TREE_TYPE_NAMES.premium,
|
.addStringOption((option) =>
|
||||||
value: 'premium' satisfies TreeTypeString,
|
addTankChoices(option).setRequired(false),
|
||||||
},
|
) as Option;
|
||||||
{
|
|
||||||
name: TREE_TYPE_NAMES.collector,
|
|
||||||
value: 'collector' satisfies TreeTypeString,
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.setRequired(false),
|
|
||||||
)
|
|
||||||
.addStringOption((option) => addTankChoices(option).setRequired(false));
|
|
||||||
});
|
|
||||||
|
|
||||||
return option;
|
|
||||||
}
|
}
|
||||||
@@ -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(
|
export function getCustomPeriodParams(
|
||||||
interaction: ChatInputCommandInteraction,
|
interaction: ChatInputCommandInteraction,
|
||||||
|
forcedNonCustomPeriod = false,
|
||||||
) {
|
) {
|
||||||
if ((interaction.options.getSubcommand() as PeriodType) === 'custom')
|
if (
|
||||||
|
!forcedNonCustomPeriod &&
|
||||||
|
(interaction.options.getSubcommand() as PeriodType) === 'custom'
|
||||||
|
) {
|
||||||
return {
|
return {
|
||||||
start: interaction.options.getInteger('start', true),
|
start: interaction.options.getInteger('start', true),
|
||||||
end: interaction.options.getInteger('end', true),
|
end: interaction.options.getInteger('end', true),
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@@ -20,11 +20,14 @@ export interface ResolvedPeriod {
|
|||||||
export default function resolvePeriodFromCommand(
|
export default function resolvePeriodFromCommand(
|
||||||
region: Region,
|
region: Region,
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
|
forcedPeriod?: PeriodType,
|
||||||
) {
|
) {
|
||||||
let name: string;
|
let name: string;
|
||||||
let start: number;
|
let start: number;
|
||||||
let end: number;
|
let end: number;
|
||||||
const periodSubcommand = interaction.options.getSubcommand() as PeriodType;
|
const periodSubcommand = forcedPeriod
|
||||||
|
? forcedPeriod
|
||||||
|
: (interaction.options.getSubcommand() as PeriodType);
|
||||||
|
|
||||||
if (periodSubcommand === 'custom') {
|
if (periodSubcommand === 'custom') {
|
||||||
const startOption = interaction.options.getInteger('start', true);
|
const startOption = interaction.options.getInteger('start', true);
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ import { psa } from '../../../core/discord/psa';
|
|||||||
export default async function handleChatInputCommand(
|
export default async function handleChatInputCommand(
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
) {
|
) {
|
||||||
const registry = (await commands)[interaction.commandName];
|
const awaitedCommands = await commands;
|
||||||
|
const registry = awaitedCommands[interaction.commandName];
|
||||||
|
|
||||||
await interaction.deferReply();
|
await interaction.deferReply();
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ import { searchClansCommand } from '../../commands/searchClans';
|
|||||||
import { searchPlayersCommand } from '../../commands/searchPlayers';
|
import { searchPlayersCommand } from '../../commands/searchPlayers';
|
||||||
import { searchTanksCommand } from '../../commands/searchTanks';
|
import { searchTanksCommand } from '../../commands/searchTanks';
|
||||||
import { statsCommand } from '../../commands/stats';
|
import { statsCommand } from '../../commands/stats';
|
||||||
|
import { todayCommand } from '../../commands/today';
|
||||||
import getClientId from '../../core/blitzkrieg/getClientId';
|
import getClientId from '../../core/blitzkrieg/getClientId';
|
||||||
import isDev from '../../core/blitzkrieg/isDev';
|
import isDev from '../../core/blitzkrieg/isDev';
|
||||||
import { secrets } from '../../core/blitzkrieg/secrets';
|
import { secrets } from '../../core/blitzkrieg/secrets';
|
||||||
@@ -52,34 +53,39 @@ export type InteractionReturnable =
|
|||||||
| InteractionIterableReturnable
|
| InteractionIterableReturnable
|
||||||
| Promise<InteractionIterableReturnable>;
|
| Promise<InteractionIterableReturnable>;
|
||||||
|
|
||||||
export interface Registry {
|
type CommandRegistryBase = {
|
||||||
inProduction: boolean;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type CommandRegistryRaw = Registry & {
|
|
||||||
inPublic: boolean;
|
|
||||||
inPreview?: boolean;
|
|
||||||
|
|
||||||
command:
|
command:
|
||||||
| SlashCommandBuilder
|
| SlashCommandBuilder
|
||||||
| SlashCommandSubcommandsOnlyBuilder
|
| SlashCommandSubcommandsOnlyBuilder
|
||||||
| Omit<SlashCommandBuilder, 'addSubcommand' | 'addSubcommandGroup'>;
|
| Omit<SlashCommandBuilder, 'addSubcommand' | 'addSubcommandGroup'>;
|
||||||
|
};
|
||||||
|
type CommandRegistryDefinitionBase = {
|
||||||
|
inProduction: boolean;
|
||||||
|
inPublic: boolean;
|
||||||
|
inPreview?: boolean;
|
||||||
|
|
||||||
autocomplete?: (interaction: AutocompleteInteraction<CacheType>) => void;
|
autocomplete?: (interaction: AutocompleteInteraction<CacheType>) => void;
|
||||||
button?: (interaction: ButtonInteraction<CacheType>) => InteractionReturnable;
|
button?: (interaction: ButtonInteraction<CacheType>) => InteractionReturnable;
|
||||||
} & (
|
};
|
||||||
| {
|
type CommandRegistryDefinitionHandlesInteraction = {
|
||||||
handlesInteraction: true;
|
handlesInteraction: true;
|
||||||
handler: (interaction: ChatInputCommandInteraction<CacheType>) => void;
|
handler: (interaction: ChatInputCommandInteraction<CacheType>) => void;
|
||||||
}
|
};
|
||||||
| {
|
type CommandRegistryDefinitionDoesHandleInteraction = {
|
||||||
handlesInteraction?: false;
|
handlesInteraction?: false;
|
||||||
handler: (
|
handler: (
|
||||||
interaction: ChatInputCommandInteraction<CacheType>,
|
interaction: ChatInputCommandInteraction<CacheType>,
|
||||||
) => InteractionReturnable;
|
) => InteractionReturnable;
|
||||||
}
|
};
|
||||||
);
|
export type CommandRegistryPromisable = CommandRegistryBase &
|
||||||
export type CommandRegistry = CommandRegistryRaw | Promise<CommandRegistryRaw>;
|
(CommandRegistryDefinitionBase &
|
||||||
|
(
|
||||||
|
| CommandRegistryDefinitionHandlesInteraction
|
||||||
|
| CommandRegistryDefinitionDoesHandleInteraction
|
||||||
|
));
|
||||||
|
export type CommandRegistry =
|
||||||
|
| CommandRegistryPromisable
|
||||||
|
| Promise<CommandRegistryPromisable>;
|
||||||
|
|
||||||
const rest = new REST().setToken(secrets.DISCORD_TOKEN);
|
const rest = new REST().setToken(secrets.DISCORD_TOKEN);
|
||||||
|
|
||||||
@@ -101,10 +107,11 @@ export const COMMANDS_RAW: CommandRegistry[] = [
|
|||||||
evolutionCommand,
|
evolutionCommand,
|
||||||
statsCommand,
|
statsCommand,
|
||||||
ratingsCommand,
|
ratingsCommand,
|
||||||
|
todayCommand,
|
||||||
];
|
];
|
||||||
|
|
||||||
export const commands = Promise.all(COMMANDS_RAW).then((rawCommands) =>
|
export const commands = Promise.all(COMMANDS_RAW).then((rawCommands) =>
|
||||||
rawCommands.reduce<Record<string, CommandRegistryRaw>>(
|
rawCommands.reduce<Record<string, CommandRegistryPromisable>>(
|
||||||
(accumulator, registry) => {
|
(accumulator, registry) => {
|
||||||
if (isDev()) registry.command.setDefaultMemberPermissions(0);
|
if (isDev()) registry.command.setDefaultMemberPermissions(0);
|
||||||
|
|
||||||
@@ -123,7 +130,7 @@ export const publicCommands: RESTPostAPIChatInputApplicationCommandsJSONBody[] =
|
|||||||
[];
|
[];
|
||||||
|
|
||||||
commands.then((awaitedCommands) => {
|
commands.then((awaitedCommands) => {
|
||||||
Object.entries(awaitedCommands).forEach(([, registry]) => {
|
Object.values(awaitedCommands).forEach((registry) => {
|
||||||
const json = registry.command.toJSON();
|
const json = registry.command.toJSON();
|
||||||
|
|
||||||
if (registry.inPublic) {
|
if (registry.inPublic) {
|
||||||
|
|||||||
Reference in new issue
Block a user