mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 10:47:04 +02:00
feat: auction command
This commit is contained in:
1 parent
a78543c60f
commit
2f7f2362bb
9 files changed
+166
-1
No files matched your search
@@ -0,0 +1,126 @@
|
||||
import {
|
||||
BlitzTankClass,
|
||||
Region,
|
||||
regionToRegionSubdomain,
|
||||
} from '@blitzkit/core';
|
||||
import { tankDefinitions } from '../core/blitzkit/nonBlockingPromises';
|
||||
import { createLocalizedCommand } from '../core/discord/createLocalizedCommand';
|
||||
import { translator } from '../core/localization/translator';
|
||||
import { CommandRegistry } from '../events/interactionCreate';
|
||||
|
||||
interface Auction {
|
||||
count: number;
|
||||
has_next: boolean;
|
||||
results: Result[];
|
||||
}
|
||||
|
||||
type Result =
|
||||
| {
|
||||
id?: number;
|
||||
type: 'vehicle';
|
||||
countable?: boolean;
|
||||
entity?: Entity;
|
||||
initial_count?: number;
|
||||
current_count?: number;
|
||||
saleable?: boolean;
|
||||
available_from?: Date;
|
||||
available_before?: Date;
|
||||
price?: Price;
|
||||
next_price?: Price | null;
|
||||
available: true;
|
||||
display?: boolean;
|
||||
next_price_datetime?: Date | null;
|
||||
next_price_timestamp?: number | null;
|
||||
}
|
||||
| {
|
||||
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';
|
||||
}
|
||||
|
||||
export const auctionCommand = new Promise<CommandRegistry>((resolve) => {
|
||||
resolve({
|
||||
command: createLocalizedCommand('auction', [
|
||||
{ subcommand: 'available' },
|
||||
{ subcommand: 'setup' },
|
||||
]),
|
||||
|
||||
async handler(interaction) {
|
||||
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>);
|
||||
const seeableTanks = data.results.filter((result) => result.available);
|
||||
const { t, translate } = translator(interaction.locale);
|
||||
|
||||
const title = `# ${t`bot.commands.auction.subcommands.available.body.title`}`;
|
||||
const subtitle = `-# ${translate(
|
||||
'bot.commands.auction.subcommands.available.body.available',
|
||||
[`${seeableTanks.length} / ${data.results.length}`],
|
||||
)}`;
|
||||
const body = seeableTanks
|
||||
.map((data, index) => {
|
||||
const tank = awaitedTankDefinitions.tanks[data.entity!.id];
|
||||
|
||||
if (!tank) return '';
|
||||
|
||||
const name = `[${tank.name}](<https://blitzkit.app/tools/tankopedia/${
|
||||
tank.id
|
||||
}>)`;
|
||||
const next = translate(
|
||||
'bot.commands.auction.subcommands.available.body.next',
|
||||
[
|
||||
`<:gold:1317173197082333244> ${data.next_price!.value.toLocaleString(
|
||||
interaction.locale,
|
||||
)}`,
|
||||
],
|
||||
);
|
||||
|
||||
return `${
|
||||
index + 1
|
||||
}. ${name} <:gold:1317173197082333244> ${data.price!.value.toLocaleString(
|
||||
interaction.locale,
|
||||
)}\n-# ${next}`;
|
||||
})
|
||||
.join('\n\n');
|
||||
|
||||
return `${title}\n${subtitle}\n\n${body}`;
|
||||
},
|
||||
});
|
||||
});
|
||||
@@ -15,6 +15,7 @@ import {
|
||||
SlashCommandSubcommandsOnlyBuilder,
|
||||
} from 'discord.js';
|
||||
import { aboutCommand } from '../../commands/about';
|
||||
import { auctionCommand } from '../../commands/auction';
|
||||
import { breakdownCommand } from '../../commands/breakdown';
|
||||
import { debugCommand } from '../../commands/debug';
|
||||
import { evolutionCommand } from '../../commands/evolution';
|
||||
@@ -76,6 +77,7 @@ interface CommandRegistryExplicit extends CommandRegistryBase {
|
||||
export type CommandRegistry = CommandRegistryImplicit | CommandRegistryExplicit;
|
||||
|
||||
export const COMMANDS_RAW: Promise<CommandRegistry>[] = [
|
||||
auctionCommand,
|
||||
permissionsCommand,
|
||||
debugCommand,
|
||||
aboutCommand,
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
import { manager } from './core/discord/manager';
|
||||
|
||||
console.log('pre manager event listeners and spawn');
|
||||
|
||||
manager
|
||||
.on('shardCreate', (shard) => {
|
||||
console.log(`🟡 Launching shard ${shard.id}`);
|
||||
shard.on('ready', () => console.log(`🟢 Launched shard ${shard.id}`));
|
||||
})
|
||||
.spawn();
|
||||
|
||||
console.log('post manager event listeners and spawn');
|
||||
@@ -6,4 +6,8 @@ console.log(`🟡 Launching bot ${client.shard?.ids[0]}`);
|
||||
|
||||
registerProcesses();
|
||||
|
||||
console.log(`post register processes on shard ${client.shard?.ids[0]}`);
|
||||
|
||||
client.login(assertSecret(import.meta.env.DISCORD_TOKEN));
|
||||
|
||||
console.log(`post client login on shard ${client.shard?.ids[0]}`);
|
||||
@@ -7,3 +7,5 @@ parentPort?.on('message', async (svg: string) => {
|
||||
const png = svgToPng(svg);
|
||||
parentPort?.postMessage(png);
|
||||
});
|
||||
|
||||
console.log(`post render thread parent port on thread ${threadId}`);
|
||||
@@ -291,6 +291,27 @@
|
||||
},
|
||||
|
||||
"commands": {
|
||||
"auction": {
|
||||
"$": "auction",
|
||||
"description": "Tanks available in the auction",
|
||||
|
||||
"subcommands": {
|
||||
"available": {
|
||||
"$": "available",
|
||||
"description": "Tanks available right now in the auction",
|
||||
"body": {
|
||||
"title": "Blitz Auction",
|
||||
"available": "%s available",
|
||||
"next": "Next price: %s"
|
||||
}
|
||||
},
|
||||
"setup": {
|
||||
"$": "setup",
|
||||
"description": "Set up a channel to receive auction updates"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
"replay": {
|
||||
"$": "replay",
|
||||
"description": "Display replay results"
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export type BlitzTankClass =
|
||||
| 'lightTank'
|
||||
| 'mediumTank'
|
||||
| 'heavyTank'
|
||||
| 'AT-SPG';
|
||||
@@ -1,5 +1,6 @@
|
||||
export * from './canSplash';
|
||||
export * from './clans';
|
||||
export * from './classes';
|
||||
export * from './constants';
|
||||
export * from './equipmentPrice';
|
||||
export * from './fetchBlitz';
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import {
|
||||
Armor,
|
||||
assertSecret,
|
||||
BlitzTankClass,
|
||||
CamouflageDefinitions,
|
||||
Consumable,
|
||||
ConsumableDefinitions,
|
||||
@@ -70,7 +71,6 @@ const blitzTankFilterDefinitionCategoryToBlitzkit: Record<
|
||||
function vector3TupleToBlitzkit(tuple: Vector3Tuple) {
|
||||
return { x: tuple[0], y: tuple[1], z: tuple[2] } satisfies Vector3;
|
||||
}
|
||||
type BlitzTankClass = 'lightTank' | 'mediumTank' | 'heavyTank' | 'AT-SPG';
|
||||
const blitzTankClassToBlitzkit: Record<BlitzTankClass, TankClass> = {
|
||||
lightTank: TankClass.LIGHT,
|
||||
'AT-SPG': TankClass.TANK_DESTROYER,
|
||||
|
||||
Reference in new issue
Block a user