From c2fca42a8624aff20474ec2f926ab60999c66a14 Mon Sep 17 00:00:00 2001 From: tresabhi Date: Tue, 30 May 2023 18:42:34 +0000 Subject: [PATCH] feat: cleaned up tankopedia --- src/commands/debug.ts | 2 +- src/commands/ownedtanks.ts | 4 +- src/commands/searchtanks.ts | 4 +- src/commands/stats.tsx | 4 +- src/commands/tankstats.tsx | 8 +- src/commands/today.tsx | 8 +- src/core/autocomplete/tanks.ts | 6 +- src/core/blitz/resolveTankId.ts | 4 +- .../blitz}/resolveTankName.ts | 2 +- src/core/blitz/tankopedia.ts | 165 ++++++++++++++++++ src/core/blitzstars/tankopedia.ts | 75 -------- .../fullBlitzStarsStats.ts | 0 .../supportBlitzStars.ts | 0 src/core/ui/URLToBase64.ts | 9 + 14 files changed, 195 insertions(+), 96 deletions(-) rename src/{utilities => core/blitz}/resolveTankName.ts (74%) create mode 100644 src/core/blitz/tankopedia.ts delete mode 100644 src/core/blitzstars/tankopedia.ts rename src/core/{actions => interaction}/fullBlitzStarsStats.ts (100%) rename src/core/{actions => interaction}/supportBlitzStars.ts (100%) create mode 100644 src/core/ui/URLToBase64.ts diff --git a/src/commands/debug.ts b/src/commands/debug.ts index 7b18e4d5a..b18d676fc 100644 --- a/src/commands/debug.ts +++ b/src/commands/debug.ts @@ -1,7 +1,7 @@ import { EmbedBuilder, SlashCommandBuilder } from 'discord.js'; import packageJSON from '../../package.json' assert { type: 'json' }; import { ACCENT_COLOR } from '../constants/colors.js'; -import { tankopedia } from '../core/blitzstars/tankopedia.js'; +import { tankopedia } from '../core/blitz/tankopedia.js'; import cmdName from '../core/interaction/cmdName.js'; import getClientId from '../core/process/getClientId.js'; import { CommandRegistry } from '../events/interactionCreate.js'; diff --git a/src/commands/ownedtanks.ts b/src/commands/ownedtanks.ts index c026bf993..069200ea0 100644 --- a/src/commands/ownedtanks.ts +++ b/src/commands/ownedtanks.ts @@ -3,7 +3,8 @@ import markdownEscape from 'markdown-escape'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; -import { TANK_TYPE_EMOJIS, tankopedia } from '../core/blitzstars/tankopedia.js'; +import resolveTankName from '../core/blitz/resolveTankName.js'; +import { TANK_TYPE_EMOJIS, tankopedia } from '../core/blitz/tankopedia.js'; import cmdName from '../core/interaction/cmdName.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; @@ -11,7 +12,6 @@ import { args } from '../core/process/args.js'; import { CommandRegistry } from '../events/interactionCreate.js'; import { AccountInfo } from '../types/accountInfo.js'; import { TanksStats } from '../types/tanksStats.js'; -import resolveTankName from '../utilities/resolveTankName.js'; const COMP_TANKS = [ // light tanks diff --git a/src/commands/searchtanks.ts b/src/commands/searchtanks.ts index bf7d49823..f14361372 100644 --- a/src/commands/searchtanks.ts +++ b/src/commands/searchtanks.ts @@ -1,7 +1,7 @@ import { SlashCommandBuilder } from 'discord.js'; import { go } from 'fuzzysort'; import markdownEscape from 'markdown-escape'; -import { tankNames } from '../core/blitzstars/tankopedia.js'; +import { TANK_NAMES } from '../core/blitz/tankopedia.js'; import cmdName from '../core/interaction/cmdName.js'; import infoEmbed from '../core/interaction/infoEmbed.js'; import addTankChoices from '../core/options/addTankChoices.js'; @@ -27,7 +27,7 @@ export default { async execute(interaction) { const tank = interaction.options.getString('tank')!; const limit = interaction.options.getInteger('limit') ?? 25; - const results = go(tank, tankNames, { limit }).map( + const results = go(tank, TANK_NAMES, { limit }).map( (result) => result.target, ); diff --git a/src/commands/stats.tsx b/src/commands/stats.tsx index 3dc9bed2c..13e2078bc 100644 --- a/src/commands/stats.tsx +++ b/src/commands/stats.tsx @@ -9,8 +9,6 @@ import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js'; import TitleBar from '../components/TitleBar.js'; import Wrapper from '../components/Wrapper.js'; import { BLITZ_SERVERS } from '../constants/servers.js'; -import fullBlitzStarsStats from '../core/actions/fullBlitzStarsStats.js'; -import { supportBlitzStars } from '../core/actions/supportBlitzStars.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; @@ -19,6 +17,8 @@ import getPeriodNow from '../core/blitzstars/getPeriodNow.js'; import getPeriodicStart from '../core/blitzstars/getPeriodStart.js'; import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js'; import cmdName from '../core/interaction/cmdName.js'; +import fullBlitzStarsStats from '../core/interaction/fullBlitzStarsStats.js'; +import { supportBlitzStars } from '../core/interaction/supportBlitzStars.js'; import addStatPeriodChoices, { StatPeriod, statPeriodNames, diff --git a/src/commands/tankstats.tsx b/src/commands/tankstats.tsx index bed654baa..61a10c796 100644 --- a/src/commands/tankstats.tsx +++ b/src/commands/tankstats.tsx @@ -9,20 +9,21 @@ import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js'; import TitleBar from '../components/TitleBar.js'; import Wrapper from '../components/Wrapper.js'; import { BLITZ_SERVERS } from '../constants/servers.js'; -import fullBlitzStarsStats from '../core/actions/fullBlitzStarsStats.js'; -import { supportBlitzStars } from '../core/actions/supportBlitzStars.js'; import tanksAutocomplete from '../core/autocomplete/tanks.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; import resolveTankId from '../core/blitz/resolveTankId.js'; +import resolveTankName from '../core/blitz/resolveTankName.js'; +import { tankopedia } from '../core/blitz/tankopedia.js'; import getPeriodNow from '../core/blitzstars/getPeriodNow.js'; import getPeriodicStart from '../core/blitzstars/getPeriodStart.js'; import getTankStatsOverTime, { emptyAllStats, } from '../core/blitzstars/getTankStatsOverTime.js'; -import { tankopedia } from '../core/blitzstars/tankopedia.js'; import cmdName from '../core/interaction/cmdName.js'; +import fullBlitzStarsStats from '../core/interaction/fullBlitzStarsStats.js'; +import { supportBlitzStars } from '../core/interaction/supportBlitzStars.js'; import addStatPeriodChoices, { StatPeriod, statPeriodNames, @@ -34,7 +35,6 @@ import render from '../core/ui/render.js'; import { CommandRegistry } from '../events/interactionCreate.js'; import { AccountInfo, AllStats } from '../types/accountInfo.js'; import { TanksStats } from '../types/tanksStats.js'; -import resolveTankName from '../utilities/resolveTankName.js'; export default { inProduction: true, diff --git a/src/commands/today.tsx b/src/commands/today.tsx index 7f756cc03..ea84232c2 100644 --- a/src/commands/today.tsx +++ b/src/commands/today.tsx @@ -9,16 +9,17 @@ import PoweredByBlitzStars from '../components/PoweredByBlitzStars.js'; import TitleBar from '../components/TitleBar.js'; import Wrapper from '../components/Wrapper.js'; import { BLITZ_SERVERS } from '../constants/servers.js'; -import fullBlitzStarsStats from '../core/actions/fullBlitzStarsStats.js'; -import { supportBlitzStars } from '../core/actions/supportBlitzStars.js'; import usernameAutocomplete from '../core/autocomplete/username.js'; import getBlitzAccount from '../core/blitz/getBlitzAccount.js'; import getWargamingResponse from '../core/blitz/getWargamingResponse.js'; +import resolveTankName from '../core/blitz/resolveTankName.js'; import sumStats from '../core/blitz/sumStats.js'; +import { tankopedia } from '../core/blitz/tankopedia.js'; import getTankStatsOverTime from '../core/blitzstars/getTankStatsOverTime.js'; import last5AM from '../core/blitzstars/last5AM.js'; -import { tankopedia } from '../core/blitzstars/tankopedia.js'; import cmdName from '../core/interaction/cmdName.js'; +import fullBlitzStarsStats from '../core/interaction/fullBlitzStarsStats.js'; +import { supportBlitzStars } from '../core/interaction/supportBlitzStars.js'; import addUsernameOption from '../core/options/addUsernameOption.js'; import { args } from '../core/process/args.js'; import render from '../core/ui/render.js'; @@ -26,7 +27,6 @@ import { CommandRegistry } from '../events/interactionCreate.js'; import { AccountInfo, AllStats } from '../types/accountInfo.js'; import { PlayerClanData } from '../types/playerClanData.js'; import { TanksStats } from '../types/tanksStats.js'; -import resolveTankName from '../utilities/resolveTankName.js'; export default { inProduction: true, diff --git a/src/core/autocomplete/tanks.ts b/src/core/autocomplete/tanks.ts index e92edb117..7d5776f7d 100644 --- a/src/core/autocomplete/tanks.ts +++ b/src/core/autocomplete/tanks.ts @@ -4,8 +4,8 @@ import { CacheType, } from 'discord.js'; import { go } from 'fuzzysort'; -import resolveTankName from '../../utilities/resolveTankName.js'; -import { tanks } from '../blitzstars/tankopedia.js'; +import resolveTankName from '../blitz/resolveTankName.js'; +import { TANKS } from '../blitz/tankopedia.js'; export default async function tanksAutocomplete( interaction: AutocompleteInteraction, @@ -15,7 +15,7 @@ export default async function tanksAutocomplete( await interaction.respond( focusedOption.value - ? go(focusedOption.value, tanks, { keys: ['name'], limit: 10 }).map( + ? go(focusedOption.value, TANKS, { keys: ['name'], limit: 10 }).map( (item) => ({ name: item.obj.name diff --git a/src/core/blitz/resolveTankId.ts b/src/core/blitz/resolveTankId.ts index fe3d71c94..95507f5d9 100644 --- a/src/core/blitz/resolveTankId.ts +++ b/src/core/blitz/resolveTankId.ts @@ -1,7 +1,7 @@ import { CacheType, ChatInputCommandInteraction } from 'discord.js'; import { go } from 'fuzzysort'; -import { tankopedia, tanks } from '../blitzstars/tankopedia.js'; import errorEmbed from '../interaction/errorEmbed.js'; +import { TANKS, tankopedia } from './tankopedia.js'; export default async function resolveTankId( interaction: ChatInputCommandInteraction, @@ -10,7 +10,7 @@ export default async function resolveTankId( const number = Number(tank); if (Number.isNaN(number)) { - const searchResult = go(tank, tanks, { keys: ['name'], limit: 1 }); + const searchResult = go(tank, TANKS, { keys: ['name'], limit: 1 }); if (searchResult.length === 0) { await interaction.editReply({ diff --git a/src/utilities/resolveTankName.ts b/src/core/blitz/resolveTankName.ts similarity index 74% rename from src/utilities/resolveTankName.ts rename to src/core/blitz/resolveTankName.ts index a17599908..2f97fdb7f 100644 --- a/src/utilities/resolveTankName.ts +++ b/src/core/blitz/resolveTankName.ts @@ -1,4 +1,4 @@ -import { tankopedia } from '../core/blitzstars/tankopedia.js'; +import { tankopedia } from './tankopedia.js'; export default function resolveTankName(tankId: number) { const tankopediaName = tankopedia[tankId].name; diff --git a/src/core/blitz/tankopedia.ts b/src/core/blitz/tankopedia.ts new file mode 100644 index 000000000..e4bd8b6ab --- /dev/null +++ b/src/core/blitz/tankopedia.ts @@ -0,0 +1,165 @@ +import { args } from '../process/args.js'; +import isDev from '../process/isDev.js'; +import URLToBase64 from '../ui/URLToBase64.js'; +import getWargamingResponse from './getWargamingResponse.js'; + +export interface Tankopedia { + [id: number]: { + description: string; + engines: number[]; + guns: number[]; + is_premium: boolean; + name: string; + nation: string; + next_tanks: { [id: number]: number }; + prices_xp: { [id: number]: number }; + suspensions: number[]; + tank_id: number; + tier: number; + turrets: number[] | null; + type: string; + cost: { + price_credit: number; + price_gold: number; + }; + default_profile: { + battle_level_range_max: number; + battle_level_range_min: number; + engine_id: number; + firepower: number; + gun_id: number; + hp: number; + hull_hp: number; + hull_weight: number; + is_default: boolean; + maneuverability: number; + max_ammo: number; + max_weight: number; + profile_id: string; + protection: number; + shot_efficiency: number; + signal_range: number; + speed_backward: number; + suspension_id: number; + turret_id: number; + weight: number; + armor: { + hull: { + front: number; + rear: number; + sides: number; + }; + turret: { + front: number; + rear: number; + sides: number; + }; + }; + engine: { + fire_chance: number; + name: string; + power: number; + tier: number; + weight: number; + }; + gun: { + aim_time: number; + caliber: number; + clip_capacity: number; + clip_reload_time: number; + dispersion: number; + fire_rate: number; + move_down_arc: number; + move_up_arc: number; + name: string; + reload_time: number; + tier: number; + traverse_speed: number; + weight: number; + }; + shells: { + damage: number; + penetration: number; + type: string; + }; + suspension: { + load_limit: number; + name: string; + tier: number; + traverse_speed: number; + weight: number; + }; + turret: { + hp: number; + name: string; + tier: number; + traverse_left_arc: number; + traverse_right_arc: number; + traverse_speed: number; + view_range: number; + weight: number; + }; + }; + images: { + normal: string; + preview: string; + }; + modules_tree: { + [id: number]: { + is_default: boolean; + module_id: number; + name: string; + next_modules: number[] | null; + next_tanks: number[] | null; + price_credit: number; + price_xp: number; + type: string; + }; + }; + }; +} + +export interface TankopediaInfo { + achievement_sections: { [name: string]: { name: string; order: number } }; + tanks_updated_at: number; + languages: { [name: string]: string }; + vehicle_types: { [name: string]: string }; + vehicle_nations: { [name: string]: string }; + game_version: string; +} + +console.log('Caching tankopedia...'); +export const tankopedia = await getWargamingResponse( + `https://api.wotblitz.com/wotb/encyclopedia/vehicles/?application_id=${args['wargaming-application-id']}`, +); +console.log('Cached tankopedia'); + +console.log('Caching tankopedia info...'); +export const tankopediaInfo = await getWargamingResponse( + `https://api.wotblitz.com/wotb/encyclopedia/info/?application_id=${args['wargaming-application-id']}`, +); +console.log('Cached tankopedia info'); + +/** + * @deprecated + */ +export const TANK_TYPE_EMOJIS: Record = { + 'AT-SPG': '🔽', + heavyTank: '🇭', + mediumTank: '🇲', + lightTank: '🇱', +}; + +export const TANK_IDS = Object.keys(tankopedia).map((id) => Number(id)); +export const TANKS = TANK_IDS.map((id) => tankopedia[id]); +export const TANK_NAMES = TANKS.map((tank) => tank.name); + +if (!isDev()) { + console.log('Encoding tank images...'); + await Promise.all( + Object.entries(tankopedia).map(async ([, tank]) => { + tank.images.normal = await URLToBase64(tank.images.normal); + }), + ); + console.log('Encoded tank images'); +} diff --git a/src/core/blitzstars/tankopedia.ts b/src/core/blitzstars/tankopedia.ts deleted file mode 100644 index 638cf29d0..000000000 --- a/src/core/blitzstars/tankopedia.ts +++ /dev/null @@ -1,75 +0,0 @@ -import isDev from '../process/isDev.js'; - -export type TankType = 'heavyTank' | 'AT-SPG' | 'mediumTank' | 'lightTank'; - -export interface Tankopedia { - status: 'ok'; // always will be ok since it is cached - meta: { - count: number; - }; - data: { - [tankId: number]: { - name?: string; - nation: string; - is_premium: boolean; - tier: number; - cost: { - price_credit: number; - price_gold: number; - }; - images: { - preview: string; - normal?: string; - }; - tank_id: number; - type: TankType; - description: string; - }; - }; -} - -console.log('Caching tankopedia...'); -export const tankopedia = ( - (await ( - await fetch('https://www.blitzstars.com/bs-tankopedia.json') - ).json()) as Tankopedia -).data; -console.log('Cached tankopedia'); - -export const tankIds = Object.keys(tankopedia) as unknown as number[]; - -export const tankNames = tankIds.map((id) => tankopedia[id].name); - -export const tanks = tankIds.map((id) => tankopedia[id]); - -export const TANK_TYPE_NAMES: Record = { - 'AT-SPG': 'Tank Destroyer', - heavyTank: 'Heavy Tank', - mediumTank: 'Medium Tank', - lightTank: 'Light Tank', -}; - -export const TANK_TYPE_EMOJIS: Record = { - 'AT-SPG': '🔽', - heavyTank: '🇭', - mediumTank: '🇲', - lightTank: '🇱', -}; - -if (!isDev()) { - console.log('Encoding tank images...'); - await Promise.all( - Object.entries(tankopedia).map(async ([, tank]) => { - if (tank.images.normal) { - const response = await fetch(tank.images.normal); - const blob = await response.arrayBuffer(); - const base64 = `data:${response.headers.get( - 'content-type', - )};base64,${Buffer.from(blob).toString('base64')}`; - - tank.images.normal = base64; - } - }), - ); - console.log('Encoded tank images'); -} diff --git a/src/core/actions/fullBlitzStarsStats.ts b/src/core/interaction/fullBlitzStarsStats.ts similarity index 100% rename from src/core/actions/fullBlitzStarsStats.ts rename to src/core/interaction/fullBlitzStarsStats.ts diff --git a/src/core/actions/supportBlitzStars.ts b/src/core/interaction/supportBlitzStars.ts similarity index 100% rename from src/core/actions/supportBlitzStars.ts rename to src/core/interaction/supportBlitzStars.ts diff --git a/src/core/ui/URLToBase64.ts b/src/core/ui/URLToBase64.ts new file mode 100644 index 000000000..31b7c9954 --- /dev/null +++ b/src/core/ui/URLToBase64.ts @@ -0,0 +1,9 @@ +export default async function URLToBase64(URL: string) { + const response = await fetch(URL); + const blob = await response.arrayBuffer(); + const base64 = `data:${response.headers.get( + 'content-type', + )};base64,${Buffer.from(blob).toString('base64')}`; + + return base64; +}