feat: added more mature periods

This commit is contained in:
TresAbhi committed 2023-08-04 18:24:20 +00:00
1 parent 91f364b76a
commit 91dc45c880
27 files changed
+68 -67

No files matched your search

+1 -1
View File
@@ -12,7 +12,7 @@ const executionStart = new Date().getTime();
export const debugCommand: CommandRegistry = { export const debugCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -26,7 +26,7 @@ export const SKILLED_CLANS: Record<SkilledClan, string> = {
export const eligibleCommand: CommandRegistry = { export const eligibleCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: false, inPublic: false,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -28,7 +28,7 @@ export const evolutionCommand = new Promise<CommandRegistryRaw>(
resolve({ resolve({
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command, command,
+1 -1
View File
@@ -27,7 +27,7 @@ export const fullStatsCommand = new Promise<CommandRegistryRaw>(
resolve({ resolve({
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command, command,
+5 -4
View File
@@ -30,7 +30,7 @@ function addDocsSubcommands(option: SlashCommandSubcommandsOnlyBuilder) {
export const helpCommand: CommandRegistry = { export const helpCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: addDocsSubcommands( command: addDocsSubcommands(
@@ -44,13 +44,14 @@ export const helpCommand: CommandRegistry = {
), ),
), ),
handler(interaction) { async handler(interaction) {
const subcommand = interaction.options.getSubcommand(); const subcommand = interaction.options.getSubcommand();
if (subcommand === 'commands') { if (subcommand === 'commands') {
return `# Commands\n\nBlitzkrieg offers the following commands:\n\n${COMMANDS_RAW.filter( return `# Commands\n\nBlitzkrieg offers the following commands:\n\n${(
(registry) => registry.inPublic && registry.inProduction, await Promise.all(COMMANDS_RAW)
) )
.filter((registry) => registry.inPublic && registry.inProduction)
.map( .map(
(registry) => (registry) =>
`- \`/${registry.command.name}\`: ${registry.command.description}`, `- \`/${registry.command.name}\`: ${registry.command.description}`,
+1 -1
View File
@@ -18,7 +18,7 @@ const DEFAULT_THRESHOLD = 7;
export const inactiveCommand: CommandRegistry = { export const inactiveCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -45,7 +45,7 @@ const COMP_TANKS = [
export const ownedTanksCommand: CommandRegistry = { export const ownedTanksCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+2 -2
View File
@@ -1,9 +1,9 @@
import { SlashCommandBuilder } from 'discord.js'; import { SlashCommandBuilder } from 'discord.js';
import { CommandRegistry } from '../events/interactionCreate'; import { CommandRegistry } from '../events/interactionCreate';
export const pingCommand: CommandRegistry<true> = { export const pingCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
handlesInteraction: true, handlesInteraction: true,
+1 -1
View File
@@ -16,7 +16,7 @@ type SortBy = 'name' | 'count';
export const playerAchievementsCommand: CommandRegistry = { export const playerAchievementsCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -12,7 +12,7 @@ import { AccountInfo } from '../types/accountInfo';
export const playerInfoCommand: CommandRegistry = { export const playerInfoCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -121,7 +121,7 @@ export const DATABASE_REPO = { owner: 'tresabhi', repo: 'blitzkrieg-db' };
export const ratingsCommand: CommandRegistry = { export const ratingsCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -11,7 +11,7 @@ import { ClanList } from '../types/clanList';
export const searchClansCommand: CommandRegistry = { export const searchClansCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -12,7 +12,7 @@ import { AccountList } from '../types/accountList';
export const searchPlayersCommand: CommandRegistry = { export const searchPlayersCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -8,7 +8,7 @@ import { CommandRegistry } from '../events/interactionCreate';
export const searchTanksCommand: CommandRegistry = { export const searchTanksCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+7 -2
View File
@@ -37,7 +37,11 @@ export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
true, true,
) as StatType; ) as StatType;
const player = await resolvePlayerFromCommand(interaction); const player = await resolvePlayerFromCommand(interaction);
const period = resolvePeriodFromCommand(player.region, interaction); const resolvedPeriod = resolvePeriodFromCommand(
player.region,
interaction,
);
const period = interaction.options.getString('period');
const tankIdRaw = interaction.options.getString('tank')!; const tankIdRaw = interaction.options.getString('tank')!;
const tankId = const tankId =
commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null; commandGroup === 'tank' ? await resolveTankId(tankIdRaw) : null;
@@ -48,6 +52,7 @@ export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
tankId, tankId,
start, start,
end, end,
period,
}); });
const { nickname } = ( const { nickname } = (
await getWargamingResponse<AccountInfo>( await getWargamingResponse<AccountInfo>(
@@ -56,7 +61,7 @@ export const statsCommand = new Promise<CommandRegistryRaw>(async (resolve) => {
)[player.id]; )[player.id];
return [ return [
await stats(commandGroup, period, player, tankId), await stats(commandGroup, resolvedPeriod, player, tankId),
primaryButton(path, 'Refresh'), primaryButton(path, 'Refresh'),
linkButton(`${CYCLIC_API}/${path}`, 'Embed'), linkButton(`${CYCLIC_API}/${path}`, 'Embed'),
linkButton( linkButton(
+1 -1
View File
@@ -15,7 +15,7 @@ import { AccountInfo } from '../types/accountInfo';
export const todayCommand: CommandRegistry = { export const todayCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+1 -1
View File
@@ -14,7 +14,7 @@ import { PlayerClanData } from '../types/playerClanData';
export const verifyCommand: CommandRegistry = { export const verifyCommand: CommandRegistry = {
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
inPublic: true, inPublic: true,
command: new SlashCommandBuilder() command: new SlashCommandBuilder()
+2 -2
View File
@@ -1,7 +1,7 @@
import { Region } from '../../constants/regions'; import { Region } from '../../constants/regions';
import { PeriodOption } from '../discord/addPeriodSubCommands'; import { PeriodSize } from '../discord/addPeriodSubCommands';
import getTimeDaysAgo from './getTimeDaysAgo'; import getTimeDaysAgo from './getTimeDaysAgo';
export default function getPeriodStart(region: Region, period: PeriodOption) { export default function getPeriodStart(region: Region, period: PeriodSize) {
return period === 'career' ? 0 : getTimeDaysAgo(region, parseInt(period)); return period === 'career' ? 0 : getTimeDaysAgo(region, parseInt(period));
} }
+13 -14
View File
@@ -2,10 +2,9 @@ import {
SlashCommandSubcommandBuilder, SlashCommandSubcommandBuilder,
SlashCommandSubcommandGroupBuilder, SlashCommandSubcommandGroupBuilder,
} from 'discord.js'; } from 'discord.js';
import { PERIOD_NAMES } from '../discord/resolvePeriodFromCommand';
export type PeriodSubcommand = 'period' | 'custom'; export type PeriodType = 'period' | 'custom';
export type PeriodOption = `${number}` | 'career'; export type PeriodSize = `${number}` | 'career';
export default function addPeriodSubCommands( export default function addPeriodSubCommands(
option: SlashCommandSubcommandGroupBuilder, option: SlashCommandSubcommandGroupBuilder,
@@ -17,18 +16,18 @@ export default function addPeriodSubCommands(
.addSubcommand((option) => .addSubcommand((option) =>
extra( extra(
option option
.setName('period' satisfies PeriodSubcommand) .setName('period' satisfies PeriodType)
.setDescription(PERIOD_NAMES.period) .setDescription("Preset period's statistics")
.addStringOption((option) => .addStringOption((option) =>
option option
.setName('period') .setName('period')
.setDescription('A preset period') .setDescription('A preset period')
.setChoices( .setChoices(
{ name: 'Today', value: '1' satisfies PeriodOption }, { name: 'Today', value: '1' satisfies PeriodSize },
{ name: '30 days', value: '30' satisfies PeriodOption }, { name: '30 days', value: '30' satisfies PeriodSize },
{ name: '60 days', value: '60' satisfies PeriodOption }, { name: '60 days', value: '60' satisfies PeriodSize },
{ name: '90 days', value: '90' satisfies PeriodOption }, { name: '90 days', value: '90' satisfies PeriodSize },
{ name: 'Career', value: 'career' satisfies PeriodOption }, { name: 'Career', value: 'career' satisfies PeriodSize },
) )
.setRequired(true), .setRequired(true),
), ),
@@ -37,19 +36,19 @@ export default function addPeriodSubCommands(
.addSubcommand((option) => .addSubcommand((option) =>
extra( extra(
option option
.setName('custom' satisfies PeriodSubcommand) .setName('custom' satisfies PeriodType)
.setDescription(PERIOD_NAMES.custom) .setDescription("Custom period's statistics")
.addIntegerOption((option) => .addIntegerOption((option) =>
option option
.setName('start') .setName('start')
.setDescription('Start of period in days ago from today') .setDescription('Days ago from today')
.setMinValue(0) .setMinValue(0)
.setRequired(true), .setRequired(true),
) )
.addIntegerOption((option) => .addIntegerOption((option) =>
option option
.setName('end') .setName('end')
.setDescription('End of period in days ago from today') .setDescription('Days ago from today')
.setMinValue(0) .setMinValue(0)
.setRequired(true), .setRequired(true),
), ),
@@ -29,6 +29,7 @@ export default async function addStatTypeSubCommandGroups(
.addSubcommandGroup((option) => .addSubcommandGroup((option) =>
addPeriodSubCommands(option, (option) => addPeriodSubCommands(option, (option) =>
option option
.addStringOption(addUsernameChoices)
.addStringOption((option) => { .addStringOption((option) => {
option option
.setName('nation') .setName('nation')
+10 -15
View File
@@ -3,17 +3,11 @@ import { Region } from '../../constants/regions';
import getPeriodNow from '../blitzstars/getPeriodNow'; import getPeriodNow from '../blitzstars/getPeriodNow';
import getPeriodStart from '../blitzstars/getPeriodStart'; import getPeriodStart from '../blitzstars/getPeriodStart';
import getTimeDaysAgo from '../blitzstars/getTimeDaysAgo'; import getTimeDaysAgo from '../blitzstars/getTimeDaysAgo';
import { PeriodSubcommand } from '../discord/addPeriodSubCommands'; import { PeriodSize, PeriodType } from '../discord/addPeriodSubCommands';
export const PERIOD_NAMES: Record<PeriodSubcommand, string> = { export function getPeriodOptionName(period: PeriodSize) {
period: "Preset period's statistics", return period === 'career' ? 'Career' : `${period}-day`;
custom: "Custom period's statistics", }
};
export const EVOLUTION_PERIOD_NAMES: Record<PeriodSubcommand, string> = {
period: "Preset period's evolution",
custom: "Custom period's evolution",
};
export interface ResolvedPeriod { export interface ResolvedPeriod {
statsName: string; statsName: string;
@@ -30,9 +24,10 @@ export default function resolvePeriodFromCommand(
let evolutionName: string; let evolutionName: string;
let start: number; let start: number;
let end: number; let end: number;
const period = interaction.options.getSubcommand() as PeriodSubcommand; const periodSubcommand = interaction.options.getSubcommand() as PeriodType;
const periodOption = interaction.options.getString('period') as PeriodSize;
if (period === 'custom') { if (periodSubcommand === 'custom') {
const startRaw = interaction.options.getInteger('start')!; const startRaw = interaction.options.getInteger('start')!;
const endRaw = interaction.options.getInteger('end')!; const endRaw = interaction.options.getInteger('end')!;
const startMin = Math.min(startRaw, endRaw); const startMin = Math.min(startRaw, endRaw);
@@ -43,9 +38,9 @@ export default function resolvePeriodFromCommand(
start = getTimeDaysAgo(server, startMin); start = getTimeDaysAgo(server, startMin);
end = getTimeDaysAgo(server, endMax); end = getTimeDaysAgo(server, endMax);
} else { } else {
statsName = PERIOD_NAMES[period]; statsName = `${getPeriodOptionName(periodOption)} Statistics`;
evolutionName = EVOLUTION_PERIOD_NAMES[period]; evolutionName = `${getPeriodOptionName(periodOption)} Evolution`;
start = getPeriodStart(server, period); start = getPeriodStart(server, periodOption);
end = getPeriodNow(); end = getPeriodNow();
} }
+8 -8
View File
@@ -2,11 +2,10 @@ import { Region } from '../../constants/regions';
import getPeriodNow from '../blitzstars/getPeriodNow'; import getPeriodNow from '../blitzstars/getPeriodNow';
import getPeriodStart from '../blitzstars/getPeriodStart'; import getPeriodStart from '../blitzstars/getPeriodStart';
import getTimeDaysAgo from '../blitzstars/getTimeDaysAgo'; import getTimeDaysAgo from '../blitzstars/getTimeDaysAgo';
import { PeriodSubcommand } from '../discord/addPeriodSubCommands'; import { PeriodSize, PeriodType } from '../discord/addPeriodSubCommands';
import { import {
EVOLUTION_PERIOD_NAMES,
PERIOD_NAMES,
ResolvedPeriod, ResolvedPeriod,
getPeriodOptionName,
} from '../discord/resolvePeriodFromCommand'; } from '../discord/resolvePeriodFromCommand';
export default function resolvePeriodFromURL( export default function resolvePeriodFromURL(
@@ -19,9 +18,10 @@ export default function resolvePeriodFromURL(
let end: number; let end: number;
const url = new URL(urlString); const url = new URL(urlString);
const path = url.pathname.split('/').filter(Boolean); const path = url.pathname.split('/').filter(Boolean);
const period = path[path.length - 1] as PeriodSubcommand; const periodSubcommand = path[path.length - 1] as PeriodType;
const periodOption = url.searchParams.get('period') as PeriodSize;
if (period === 'custom') { if (periodSubcommand === 'custom') {
const startRaw = parseInt(url!.searchParams.get('start')!); const startRaw = parseInt(url!.searchParams.get('start')!);
const endRaw = parseInt(url!.searchParams.get('end')!); const endRaw = parseInt(url!.searchParams.get('end')!);
const startMin = Math.min(startRaw, endRaw); const startMin = Math.min(startRaw, endRaw);
@@ -32,9 +32,9 @@ export default function resolvePeriodFromURL(
start = getTimeDaysAgo(server, startMin); start = getTimeDaysAgo(server, startMin);
end = getTimeDaysAgo(server, endMax); end = getTimeDaysAgo(server, endMax);
} else { } else {
statsName = PERIOD_NAMES[period]; statsName = `${getPeriodOptionName(periodOption)} Statistics`;
evolutionName = EVOLUTION_PERIOD_NAMES[period]; evolutionName = `${getPeriodOptionName(periodOption)} Evolution`;
start = getPeriodStart(server, period); start = getPeriodStart(server, periodOption);
end = getPeriodNow(); end = getPeriodNow();
} }
@@ -1,10 +1,10 @@
import { AutocompleteInteraction, CacheType } from 'discord.js'; import { AutocompleteInteraction, CacheType } from 'discord.js';
import { commands } from '..'; import { commands } from '..';
export default function handleAutocomplete( export default async function handleAutocomplete(
interaction: AutocompleteInteraction<CacheType>, interaction: AutocompleteInteraction<CacheType>,
) { ) {
const command = commands[interaction.commandName]; const command = (await commands)[interaction.commandName];
if (!command) { if (!command) {
console.error(`No command matching ${interaction.commandName} was found.`); console.error(`No command matching ${interaction.commandName} was found.`);
@@ -11,7 +11,7 @@ export default async function handleButton(
const url = new URL(`${CYCLIC_API}/${interaction.customId}`); const url = new URL(`${CYCLIC_API}/${interaction.customId}`);
const commandName = url.pathname.split('/')[1]; const commandName = url.pathname.split('/')[1];
const button = commands[commandName]?.button; const button = (await commands)[commandName]?.button;
if (!button) { if (!button) {
throwError(`Button handler not found for "${commandName}"`); throwError(`Button handler not found for "${commandName}"`);
@@ -16,7 +16,7 @@ import { handleError } from '../../error';
export default async function handleChatInputCommand( export default async function handleChatInputCommand(
interaction: ChatInputCommandInteraction<CacheType>, interaction: ChatInputCommandInteraction<CacheType>,
) { ) {
const registry = commands[interaction.commandName]; const registry = (await commands)[interaction.commandName];
console.log(interaction.toString()); console.log(interaction.toString());
await interaction.deferReply(); await interaction.deferReply();
+1 -1
View File
@@ -6,7 +6,7 @@ import { RouteRegistry } from '../server';
export const statsRoute: RouteRegistry = { export const statsRoute: RouteRegistry = {
route: '/stats/:type/:period', route: '/stats/:type/:period',
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
async handler(req) { async handler(req) {
const type = req.params.type as StatType; const type = req.params.type as StatType;
+1 -1
View File
@@ -5,7 +5,7 @@ import { RouteRegistry } from '../server';
export const todayRoute: RouteRegistry = { export const todayRoute: RouteRegistry = {
route: '/today', route: '/today',
inProduction: true, inProduction: true,
inDevelopment: false, inDevelopment: true,
async handler(req) { async handler(req) {
const player = resolvePlayerFromRequest(req); const player = resolvePlayerFromRequest(req);