From 40a1eb861df8193b6f216e290b58a50446525060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Fri, 26 Dec 2025 14:14:29 -0600 Subject: [PATCH] feat: meta section --- bun.lock | 1 + packages/scripts/src/protos.ts | 5 +- packages/website-ue/package.json | 1 + packages/website-ue/src/core/api/abstract.ts | 4 +- packages/website-ue/src/core/api/client.ts | 4 +- packages/website-ue/src/core/api/server.ts | 6 ++- .../src/core/tankopedia/characteristics.ts | 31 ++++++++++++- .../core/tankopedia/characteristicsOrder.ts | 46 ++++++++++++++++++- .../core/tankopedia/computeCharacteristics.ts | 5 ++ .../core/tankopedia/renderCharacteristic.ts | 6 +++ .../src/pages/api/enums/[enum].json.ts | 27 +++++++++++ .../website-ue/src/pages/api/tanks/[id].pb.ts | 4 +- .../src/pages/tanks/[slug]/_index.tsx | 8 ++-- packages/website-ue/src/protos/tank.proto | 11 +++++ 14 files changed, 141 insertions(+), 18 deletions(-) create mode 100644 packages/website-ue/src/pages/api/enums/[enum].json.ts create mode 100644 packages/website-ue/src/protos/tank.proto diff --git a/bun.lock b/bun.lock index 0f3ded342..06d5d5fe7 100644 --- a/bun.lock +++ b/bun.lock @@ -186,6 +186,7 @@ "@blitzkit/closed": "workspace:*", "@blitzkit/core": "workspace:*", "@blitzkit/i18n": "workspace:*", + "@bufbuild/protobuf": "^2.10.2", "@fontsource-variable/inter": "^5.2.8", "@radix-ui/colors": "^3.0.0", "@radix-ui/react-icons": "^1.3.2", diff --git a/packages/scripts/src/protos.ts b/packages/scripts/src/protos.ts index d84c3100f..709bf7f1d 100644 --- a/packages/scripts/src/protos.ts +++ b/packages/scripts/src/protos.ts @@ -56,7 +56,7 @@ for (const root of roots) { "--ts_proto_opt=unrecognizedEnum=false", "--ts_proto_opt=snakeToCamel=false", `--ts_proto_out=${root}`, - `-I=${root}`, + ...roots.map((root) => `-I=${root}`), ].join(" "); while (true) { @@ -66,8 +66,9 @@ for (const root of roots) { const newLine = ` ${root}/${file}`; if (command.length + newLine.length < MAX_COMMAND_LENGTH) { + const file = files.pop(); command += newLine; - console.log(` ${files.pop()}`); + // console.log(` ${file}`); } else { break; } diff --git a/packages/website-ue/package.json b/packages/website-ue/package.json index 2a6119710..c9af667b7 100644 --- a/packages/website-ue/package.json +++ b/packages/website-ue/package.json @@ -16,6 +16,7 @@ "@blitzkit/closed": "workspace:*", "@blitzkit/core": "workspace:*", "@blitzkit/i18n": "workspace:*", + "@bufbuild/protobuf": "^2.10.2", "@fontsource-variable/inter": "^5.2.8", "@radix-ui/colors": "^3.0.0", "@radix-ui/react-icons": "^1.3.2", diff --git a/packages/website-ue/src/core/api/abstract.ts b/packages/website-ue/src/core/api/abstract.ts index 250eed5bc..111be5b0e 100644 --- a/packages/website-ue/src/core/api/abstract.ts +++ b/packages/website-ue/src/core/api/abstract.ts @@ -1,4 +1,4 @@ -import type { TankCatalogComponent } from "@protos/blitz_static_tank_component"; +import type { Tank } from "../../protos/tank"; import type { Tanks } from "../../protos/tanks"; export abstract class AbstractAPI { @@ -9,5 +9,5 @@ export abstract class AbstractAPI { prefix?: string ): Promise>; - abstract tank(id: string): Promise; + abstract tank(id: string): Promise; } diff --git a/packages/website-ue/src/core/api/client.ts b/packages/website-ue/src/core/api/client.ts index 7d04d4714..65d054ccb 100644 --- a/packages/website-ue/src/core/api/client.ts +++ b/packages/website-ue/src/core/api/client.ts @@ -1,4 +1,4 @@ -import { TankCatalogComponent } from "@protos/blitz_static_tank_component"; +import { Tank } from "../../protos/tank"; import { AbstractAPI } from "./abstract"; export class ClientAPI extends AbstractAPI { @@ -7,6 +7,6 @@ export class ClientAPI extends AbstractAPI { const buffer = await response.arrayBuffer(); const array = new Uint8Array(buffer); - return TankCatalogComponent.decode(array); + return Tank.decode(array); } } diff --git a/packages/website-ue/src/core/api/server.ts b/packages/website-ue/src/core/api/server.ts index 05bda47d2..65847544e 100644 --- a/packages/website-ue/src/core/api/server.ts +++ b/packages/website-ue/src/core/api/server.ts @@ -2,6 +2,7 @@ import type { MetadataAccessor } from "@blitzkit/closed"; import { sluggify } from "@blitzkit/core"; import type { RemoteStorageComponent } from "@protos/blitz_static_remote_storage_component"; import { parse } from "yaml"; +import type { Tank } from "../../protos/tank"; import type { TanksEntry } from "../../protos/tanks"; import { AbstractAPI } from "./abstract"; @@ -115,8 +116,9 @@ export class ServerAPI extends AbstractAPI { async tank(id: string) { const item = this.metadata.item(`TankEntity.${id}`); - const tankCatalog = item.TankCatalog(); + const tank = item.TankCatalog(); + const compensation = item.Compensation(); - return tankCatalog; + return { tank, compensation } satisfies Tank; } } diff --git a/packages/website-ue/src/core/tankopedia/characteristics.ts b/packages/website-ue/src/core/tankopedia/characteristics.ts index 881f7b546..4d826b11e 100644 --- a/packages/website-ue/src/core/tankopedia/characteristics.ts +++ b/packages/website-ue/src/core/tankopedia/characteristics.ts @@ -1,5 +1,6 @@ import { TankClass } from "@blitzkit/core"; -import type { TankCatalogComponent } from "@protos/blitz_static_tank_component"; +import type { CompensationComponent } from "@protos/blitz_static_compensation_component"; +import { type TankCatalogComponent } from "@protos/blitz_static_tank_component"; import { ShellUpgrageSingleChange_AttributeName, StageParameters, @@ -9,7 +10,7 @@ import { radToDeg } from "three/src/math/MathUtils.js"; import { applyPitchYawLimits } from "./applyPitchYawLimits"; import { TerrainHardness, type TankState } from "./tankState"; -export type CharacteristicOutput = number | number[] | null; +export type CharacteristicOutput = number | number[] | string | null; type Characteristic = (helpers: { characteristic: (name: CharacteristicName) => CharacteristicOutput; @@ -20,6 +21,8 @@ type Characteristic = (helpers: { state: TankState; tank: TankCatalogComponent; parameters: StageParameters; + compensation: CompensationComponent; + id: string; }) => CharacteristicOutput; export type CharacteristicName = keyof typeof characteristics; @@ -391,4 +394,28 @@ export const characteristics = { volume() { return -Infinity; }, + + nation({ tank }) { + return tank.nation; + }, + + name({ tank }) { + return tank.name!.value; + }, + + tier({ tank }) { + return tank.tier_catalog_id; + }, + + type({ tank }) { + return tank.tank_type; + }, + + id({ id }) { + return id; + }, + + compensation({ compensation }) { + return compensation.compensation?.currency_reward?.amount ?? null; + }, } satisfies Record; diff --git a/packages/website-ue/src/core/tankopedia/characteristicsOrder.ts b/packages/website-ue/src/core/tankopedia/characteristicsOrder.ts index 1687e819c..f9e134571 100644 --- a/packages/website-ue/src/core/tankopedia/characteristicsOrder.ts +++ b/packages/website-ue/src/core/tankopedia/characteristicsOrder.ts @@ -1,4 +1,13 @@ -import type { CharacteristicName } from "./characteristics"; +import { + Nation, + TankClass, + TankType, +} from "@protos/blitz_static_tank_component"; +import { + GunType, + type CharacteristicName, + type CharacteristicOutput, +} from "./characteristics"; export enum BetterDirection { Higher, @@ -9,6 +18,7 @@ export interface CharacteristicRenderConfig { name: CharacteristicName; decimals?: number; units?: string; + render?: (output: CharacteristicOutput) => string; } type CharacteristicsOrder = { @@ -22,10 +32,42 @@ type CharacteristicsOrder = { }[]; export const characteristicsOrder: CharacteristicsOrder = [ + { + group: "meta", + order: [ + { name: "name" }, + { name: "tier" }, + { + name: "nation", + render(output) { + return Nation[output as Nation]; + }, + }, + { + name: "class", + render(output) { + return TankClass[output as TankClass]; + }, + }, + { + name: "type", + render(output) { + return TankType[output as TankType]; + }, + }, + { name: "compensation" }, + { name: "id" }, + ], + }, { group: "firepower", order: [ - { name: "gun_type" }, + { + name: "gun_type", + render(output) { + return GunType[output as GunType]; + }, + }, { name: "dpm", decimals: 0, units: "hp_min" }, { name: "reload", decimals: 2, units: "s" }, { name: "reloads", decimals: 2, units: "s" }, diff --git a/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts b/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts index 90027a518..6bd9ecabc 100644 --- a/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts +++ b/packages/website-ue/src/core/tankopedia/computeCharacteristics.ts @@ -1,3 +1,4 @@ +import type { CompensationComponent } from "@protos/blitz_static_compensation_component"; import type { TankCatalogComponent } from "@protos/blitz_static_tank_component"; import { ShellUpgrageSingleChange_AttributeName, @@ -12,7 +13,9 @@ import { import type { TankState } from "./tankState"; export function computeCharacteristics( + id: string, tank: TankCatalogComponent, + compensation: CompensationComponent, state: TankState ) { const parameters = aggregateStageParameters( @@ -89,6 +92,8 @@ export function computeCharacteristics( state, tank, parameters, + id, + compensation, }); computed[name] = value; } diff --git a/packages/website-ue/src/core/tankopedia/renderCharacteristic.ts b/packages/website-ue/src/core/tankopedia/renderCharacteristic.ts index 6aa096bf4..1cdaf5887 100644 --- a/packages/website-ue/src/core/tankopedia/renderCharacteristic.ts +++ b/packages/website-ue/src/core/tankopedia/renderCharacteristic.ts @@ -7,6 +7,8 @@ export function renderCharacteristic( ): string | null { if (characteristic === null) return null; + if (config.render) return config.render(characteristic); + if (typeof characteristic === "number") { if (Number.isFinite(characteristic)) { if (config.decimals === undefined) { @@ -19,5 +21,9 @@ export function renderCharacteristic( return `${characteristic < 0 ? "-" : ""}∞`; } + if (typeof characteristic === "string") { + return characteristic; + } + return characteristic.map((c) => renderCharacteristic(c, config)).join(", "); } diff --git a/packages/website-ue/src/pages/api/enums/[enum].json.ts b/packages/website-ue/src/pages/api/enums/[enum].json.ts new file mode 100644 index 000000000..35cef46b4 --- /dev/null +++ b/packages/website-ue/src/pages/api/enums/[enum].json.ts @@ -0,0 +1,27 @@ +import { Nation } from "@protos/blitz_static_tank_component"; +import type { APIContext, GetStaticPaths } from "astro"; + +const enums = { + nation: Nation, +}; + +export const getStaticPaths = (() => { + return Object.keys(enums).map((name) => ({ params: { enum: name } })); +}) satisfies GetStaticPaths; + +/** + * The one who wipes, swipes. + */ +export function GET({ + params, +}: APIContext) { + const map: Record = {}; + + for (const key in enums[params.enum]) { + const value = enums[params.enum][key]; + if (typeof value !== "string") continue; + map[key] = value; + } + + return Response.json(map); +} diff --git a/packages/website-ue/src/pages/api/tanks/[id].pb.ts b/packages/website-ue/src/pages/api/tanks/[id].pb.ts index 9897df41e..b24ace9e0 100644 --- a/packages/website-ue/src/pages/api/tanks/[id].pb.ts +++ b/packages/website-ue/src/pages/api/tanks/[id].pb.ts @@ -1,6 +1,6 @@ -import { TankCatalogComponent } from "@protos/blitz_static_tank_component"; import type { APIContext, GetStaticPaths } from "astro"; import { api } from "../../../core/api/dynamic"; +import { Tank } from "../../../protos/tank"; export const getStaticPaths = (async () => { const { tanks } = await api.tanks(); @@ -13,5 +13,5 @@ export const getStaticPaths = (async () => { */ export async function GET({ params }: APIContext) { const tank = await api.tank(params.id); - return new Response(TankCatalogComponent.encode(tank).finish()); + return new Response(Tank.encode(tank).finish()); } diff --git a/packages/website-ue/src/pages/tanks/[slug]/_index.tsx b/packages/website-ue/src/pages/tanks/[slug]/_index.tsx index f3c3a669d..115d7fcba 100644 --- a/packages/website-ue/src/pages/tanks/[slug]/_index.tsx +++ b/packages/website-ue/src/pages/tanks/[slug]/_index.tsx @@ -17,13 +17,13 @@ export function Page({ id }: { id: string }) { } function Content({ id }: { id: string }) { - const tank = useAwait(() => api.tank(id), `tank-${id}`); + const { tank, compensation } = useAwait(() => api.tank(id), `tank-${id}`); - Tankopedia.useInitialization(tank.upgrade_stages.length); + Tankopedia.useInitialization(tank!.upgrade_stages.length); const protagonist = Tankopedia.use((state) => state.protagonist); const { characteristics, parameters } = useMemo( - () => computeCharacteristics(tank, protagonist), + () => computeCharacteristics(id, tank!, compensation!, protagonist), [protagonist] ); @@ -34,7 +34,7 @@ function Content({ id }: { id: string }) {
- {times(tank.upgrade_stages.length + 1, (index) => ( + {times(tank!.upgrade_stages.length + 1, (index) => (