2024-12-13 10:58:16 -06:00
|
|
|
import {
|
|
|
|
|
BlitzTankClass,
|
|
|
|
|
Region,
|
|
|
|
|
regionToRegionSubdomain,
|
|
|
|
|
} from '@blitzkit/core';
|
2025-01-15 20:14:05 -06:00
|
|
|
import { literals } from '@blitzkit/i18n';
|
2024-12-13 10:58:16 -06:00
|
|
|
import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises';
|
2024-12-14 14:41:50 -06:00
|
|
|
import { chunkLines } from '../core/discord/chunkLines';
|
2024-12-13 10:58:16 -06:00
|
|
|
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
|
|
|
|
import { translator } from '../core/localization/translator';
|
|
|
|
|
import { CommandRegistry } from '../events/interactionCreate';
|
|
|
|
|
|
2025-01-16 14:22:30 -06:00
|
|
|
type Auction = null | {
|
2024-12-13 10:58:16 -06:00
|
|
|
count: number;
|
|
|
|
|
has_next: boolean;
|
|
|
|
|
results: Result[];
|
2025-01-16 14:22:30 -06:00
|
|
|
};
|
2024-12-13 10:58:16 -06:00
|
|
|
|
|
|
|
|
type Result =
|
|
|
|
|
| {
|
|
|
|
|
id?: number;
|
|
|
|
|
type: 'vehicle';
|
|
|
|
|
countable?: boolean;
|
|
|
|
|
entity?: Entity;
|
2024-12-13 16:25:37 -06:00
|
|
|
initial_count: number;
|
|
|
|
|
current_count: number;
|
2024-12-13 10:58:16 -06:00
|
|
|
saleable?: boolean;
|
|
|
|
|
available_from?: Date;
|
|
|
|
|
available_before?: Date;
|
|
|
|
|
price?: Price;
|
2024-12-16 10:41:10 -06:00
|
|
|
next_price: Price | null;
|
2024-12-13 10:58:16 -06:00
|
|
|
available: true;
|
|
|
|
|
display?: boolean;
|
2024-12-13 16:11:43 -06:00
|
|
|
next_price_datetime: Date;
|
|
|
|
|
next_price_timestamp: number;
|
2024-12-13 10:58:16 -06:00
|
|
|
}
|
|
|
|
|
| {
|
|
|
|
|
available: false;
|
|
|
|
|
type: 'vehicle';
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
interface Entity {
|
|
|
|
|
id: number;
|
|
|
|
|
name: string;
|
|
|
|
|
nation: string;
|
|
|
|
|
subnation: string;
|
|
|
|
|
use_subnation_flag: boolean;
|
|
|
|
|
type_slug: BlitzTankClass;
|
|
|
|
|
level: number;
|
|
|
|
|
roman_level: string;
|
|
|
|
|
user_string: string;
|
|
|
|
|
image_url: string;
|
|
|
|
|
preview_image_url: string;
|
|
|
|
|
is_premium: boolean;
|
|
|
|
|
is_collectible: boolean;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface Price {
|
|
|
|
|
currency: Currency;
|
|
|
|
|
value: number;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
interface Currency {
|
|
|
|
|
name: 'gold';
|
|
|
|
|
count: number;
|
|
|
|
|
title: 'Gold';
|
|
|
|
|
image_url: string;
|
|
|
|
|
sizes: unknown;
|
|
|
|
|
type: 'currency';
|
|
|
|
|
}
|
|
|
|
|
|
2024-12-15 19:06:05 -06:00
|
|
|
const WARNING_COUNT = 500;
|
|
|
|
|
|
2024-12-13 10:58:16 -06:00
|
|
|
export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
|
|
|
|
|
resolve({
|
2024-12-13 16:11:43 -06:00
|
|
|
command: createLocalizedCommand('auction'),
|
2024-12-13 10:58:16 -06:00
|
|
|
|
|
|
|
|
async handler(interaction) {
|
2025-01-15 20:14:05 -06:00
|
|
|
const { strings } = translator(interaction.locale);
|
2024-12-13 10:58:16 -06:00
|
|
|
const awaitedTankDefinitions = await tankDefinitions;
|
|
|
|
|
const region: Region = 'com';
|
|
|
|
|
const pageSize = 80;
|
|
|
|
|
const saleable = true;
|
|
|
|
|
const data = await fetch(
|
|
|
|
|
`https://${regionToRegionSubdomain(
|
|
|
|
|
region,
|
|
|
|
|
)}.wotblitz.com/en/api/events/items/auction/?page_size=${
|
|
|
|
|
pageSize
|
|
|
|
|
}&type[]=vehicle&saleable=${saleable}`,
|
|
|
|
|
).then((response) => response.json() as Promise<Auction>);
|
|
|
|
|
|
2025-01-16 14:22:30 -06:00
|
|
|
if (data === null) {
|
2025-01-15 20:14:05 -06:00
|
|
|
return strings.bot.commands.auction.errors.no_auction;
|
2024-12-13 16:11:43 -06:00
|
|
|
}
|
|
|
|
|
|
2025-01-16 14:22:30 -06:00
|
|
|
const saleableTanks = data.results.filter((result) => result.available);
|
2024-12-13 16:11:43 -06:00
|
|
|
const nextPricesTimestamp = saleableTanks[0].next_price_timestamp;
|
|
|
|
|
|
2025-01-15 20:14:05 -06:00
|
|
|
const title = `# ${strings.bot.commands.auction.body.title}`;
|
|
|
|
|
const subtitle = `${literals(strings.bot.commands.auction.body.subtitle, [
|
2024-12-13 16:11:43 -06:00
|
|
|
`${saleableTanks.length} / ${data.results.length}`,
|
|
|
|
|
`<t:${nextPricesTimestamp}:R>`,
|
|
|
|
|
'<https://wotblitz.com/auction/>',
|
|
|
|
|
])}`;
|
2024-12-14 14:41:50 -06:00
|
|
|
const body = saleableTanks.map((data, index) => {
|
|
|
|
|
const tank = awaitedTankDefinitions.tanks[data.entity!.id];
|
2024-12-13 10:58:16 -06:00
|
|
|
|
2024-12-14 14:41:50 -06:00
|
|
|
if (!tank) return '';
|
2024-12-13 10:58:16 -06:00
|
|
|
|
2025-05-15 23:44:20 -05:00
|
|
|
const name = `[${tank.name}](<https://blitzkit.app/tanks/${
|
|
|
|
|
tank.slug
|
2024-12-14 14:41:50 -06:00
|
|
|
}>)`;
|
2024-12-16 10:41:10 -06:00
|
|
|
const next =
|
|
|
|
|
data.next_price === null
|
|
|
|
|
? ''
|
2025-01-15 20:14:05 -06:00
|
|
|
: `\n-# ${literals(strings.bot.commands.auction.body.next, [
|
2024-12-16 10:41:10 -06:00
|
|
|
`<:gold:1317173197082333244> ${data.next_price.value.toLocaleString(
|
|
|
|
|
interaction.locale,
|
|
|
|
|
)}`,
|
|
|
|
|
])}`;
|
2025-01-15 20:14:05 -06:00
|
|
|
const available = literals(
|
|
|
|
|
strings.bot.commands.auction.body.available,
|
|
|
|
|
[
|
|
|
|
|
data.current_count.toLocaleString(interaction.locale),
|
|
|
|
|
data.initial_count.toLocaleString(interaction.locale),
|
|
|
|
|
],
|
|
|
|
|
);
|
2024-12-15 19:06:05 -06:00
|
|
|
const isOut = data.current_count === 0;
|
|
|
|
|
const outString = isOut ? '~~' : '';
|
|
|
|
|
const isLow = data.current_count <= WARNING_COUNT;
|
2024-12-13 10:58:16 -06:00
|
|
|
|
2024-12-15 19:06:05 -06:00
|
|
|
return `${index + 1}. ${
|
|
|
|
|
outString
|
|
|
|
|
}${name} <:gold:1317173197082333244> ${data.price!.value.toLocaleString(
|
2024-12-14 14:41:50 -06:00
|
|
|
interaction.locale,
|
2024-12-16 10:41:10 -06:00
|
|
|
)}${outString}\n-#${isLow ? ' ‼️ ' : ' '}${available}${isOut ? '' : next}`;
|
2024-12-14 14:41:50 -06:00
|
|
|
});
|
|
|
|
|
const header = `${title}\n${subtitle}`;
|
|
|
|
|
const lines = [header, ...body];
|
|
|
|
|
|
|
|
|
|
return chunkLines(lines, '\n\n');
|
2024-12-13 10:58:16 -06:00
|
|
|
},
|
|
|
|
|
});
|
|
|
|
|
});
|