diff --git a/.gitignore b/.gitignore index 8834744dc..efe1d5f02 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,7 @@ package-lock.json dist/ dist.* yarn-error.log -/test.* +test.* /docs/.vitepress/dist /docs/.vitepress/cache servers.csv diff --git a/bun.lockb b/bun.lockb index fd6f0fc4e..972b90a46 100644 Binary files a/bun.lockb and b/bun.lockb differ diff --git a/package.json b/package.json index 6ea76e4e5..2f40351f8 100644 --- a/package.json +++ b/package.json @@ -39,6 +39,7 @@ }, "license": "MIT", "dependencies": { + "sharp": "^0.33.5", "lodash-es": "^4.17.21" }, "devDependencies": { diff --git a/packages/core/package.json b/packages/core/package.json index 754066640..e1d3c36f8 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -13,7 +13,6 @@ "lz4js": "^0.2.0", "pickleparser": "^0.2.1", "protobufjs": "^7.4.0", - "sharp": "^0.33.5", "ts-proto": "^2.2.2", "yaml": "^2.5.0" }, diff --git a/packages/scripts/package.json b/packages/scripts/package.json index 71d7a122c..f62b1ebb5 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -13,15 +13,16 @@ "build:ratingleaderboard": "bun src/buildRatingLeaderboard.ts" }, "dependencies": { - "esbuild": "^0.19.12", "@blitzkit/core": "workspace:*", "@gltf-transform/core": "^4.0.10", "@gltf-transform/extensions": "^4.0.10", "@gltf-transform/functions": "^4.0.10", "csv-parse": "^5.5.6", "decompress": "^4.2.1", + "esbuild": "^0.19.12", "fast-xml-parser": "^4.4.1", - "progress": "^2.0.3" + "progress": "^2.0.3", + "puppeteer": "^23.10.4" }, "devDependencies": { "@types/decompress": "^4.2.7", diff --git a/packages/scripts/src/buildAssets/tankIcons.ts b/packages/scripts/src/buildAssets/tankIcons.ts index d3421c42d..04f462791 100644 --- a/packages/scripts/src/buildAssets/tankIcons.ts +++ b/packages/scripts/src/buildAssets/tankIcons.ts @@ -1,99 +1,42 @@ -import { NATION_IDS } from '@blitzkit/core'; -import { readdir } from 'fs/promises'; +import { fetchTankDefinitions } from '@blitzkit/core'; +import { exec } from 'child_process'; +import { launch } from 'puppeteer'; import sharp from 'sharp'; -import { Vector3Tuple } from 'three'; -import { readDVPLFile } from '../core/blitz/readDVPLFile'; -import { readXMLDVPL } from '../core/blitz/readXMLDVPL'; -import { readYAMLDVPL } from '../core/blitz/readYAMLDVPL'; import { commitAssets } from '../core/github/commitAssets'; import { FileChange } from '../core/github/commitMultipleFiles'; -import { DATA } from './constants'; -import { VehicleDefinitionList } from './definitions'; - -export interface TankParameters { - resourcesPath: { - smallIconPath: string; - bigIconPath: string; - blitzModelPath: string; - }; - collision: { - [key: string]: { - points: Vector3Tuple; - bbox: { - min: Vector3Tuple; - max: Vector3Tuple; - }; - averageThickness?: Record; - }; - }; - maskSlice?: { - [key: string]: - | { - enabled: boolean; - planePosition: Vector3Tuple; - planeNormal: Vector3Tuple; - planeAxis: Vector3Tuple; - frustumConeBaseRadius: number; - frustumConeAngleDegrees: number; - planeSliceMode: number; - frustumConeSliceMode: number; - } - | undefined; - }; -} export async function tankIcons() { console.log('Building tank icons...'); - const changes: FileChange[] = []; - const nations = await readdir(`${DATA}/XML/item_defs/vehicles`).then( - (nations) => nations.filter((nation) => nation !== 'common'), - ); + const websiteProcess = exec('cd ../.. && bun dev:website'); + const browser = await launch(); + const page = await browser.newPage(); + const tankDefinitions = await fetchTankDefinitions(); + const tanks = Object.values(tankDefinitions.tanks); + const files: FileChange[] = []; - await Promise.all( - nations.map(async (nation) => { - const tanks = await readXMLDVPL<{ root: VehicleDefinitionList }>( - `${DATA}/XML/item_defs/vehicles/${nation}/list.xml.dvpl`, - ); + let index = 0; + for (const { id, name } of tanks) { + await page.setViewport({ width: 640 - 1, height: 480 }); + await page.goto(`http://localhost:4321/api/tankopedia/tank-icon/${id}/`, { + waitUntil: 'networkidle0', + }); + const screenshot = await page.screenshot({ + type: 'webp', + omitBackground: true, + }); + const content = await sharp(screenshot).trim({ threshold: 100 }).toBuffer(); - await Promise.all( - Object.entries(tanks.root).map(async ([tankKey, tank]) => { - if (tankKey.includes('tutorial_bot')) return; + index++; + console.log( + `Rendered ${id} (${name}) ${((index / tanks.length) * 100).toFixed(2)}%`, + ); - const nationVehicleId = tank.id; - const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1; - const parameters = await readYAMLDVPL( - `${DATA}/3d/Tanks/Parameters/${nation}/${tankKey}.yaml.dvpl`, - ); - const smallPath = `${DATA}/${parameters.resourcesPath.smallIconPath - .replace(/~res:\//, '') - .replace(/\..+/, '')}.packed.webp.dvpl`; - const bigPath = `${DATA}/${parameters.resourcesPath.bigIconPath - .replace(/~res:\//, '') - .replace(/\..+/, '')}.packed.webp.dvpl`; - const big = await sharp(await readDVPLFile(bigPath)) - .trim() - .toBuffer(); - const small = await sharp(await readDVPLFile(smallPath)) - .trim() - .toBuffer(); + files.push({ path: `icons/tanks/blitzkit/${id}.webp`, content }); + } - if (big) { - changes.push({ - content: big, - path: `icons/tanks/big/${id}.webp`, - }); - } - if (small) { - changes.push({ - content: small, - path: `icons/tanks/small/${id}.webp`, - }); - } - }), - ); - }), - ); + websiteProcess.kill('SIGHUP'); + await browser.close(); - await commitAssets('tank icons', changes); + await commitAssets('tank icons', files); } diff --git a/packages/website/src/components/TankCard/index.tsx b/packages/website/src/components/TankCard/index.tsx index 8dcce6a72..406d02f6c 100644 --- a/packages/website/src/components/TankCard/index.tsx +++ b/packages/website/src/components/TankCard/index.tsx @@ -1,4 +1,4 @@ -import { asset, tankIcon, TankType, type TankDefinition } from '@blitzkit/core'; +import { asset, TankType, type TankDefinition } from '@blitzkit/core'; import { Flex, Link, Text, type TextProps } from '@radix-ui/themes'; import { uniq } from 'lodash-es'; import { forwardRef, type ReactNode } from 'react'; @@ -70,7 +70,7 @@ export const TankCard = forwardRef( > {tank.name} diff --git a/packages/website/src/stores/tankopediaPersistent/index.ts b/packages/website/src/stores/tankopediaPersistent/index.ts index d8054b75a..2313104b5 100644 --- a/packages/website/src/stores/tankopediaPersistent/index.ts +++ b/packages/website/src/stores/tankopediaPersistent/index.ts @@ -1,7 +1,6 @@ import * as lodash from 'lodash-es'; import { create } from 'zustand'; import { persist, subscribeWithSelector } from 'zustand/middleware'; -import { ENVIRONMENTS } from '../../constants/lightingEnvironments'; import { createContextualStore } from '../../core/zustand/createContextualStore'; import { SORT_NAMES } from './constants'; @@ -13,10 +12,8 @@ export interface TankopediaPersistentStore { wireframe: boolean; opaque: boolean; advancedHighlighting: boolean; - environment: (typeof ENVIRONMENTS)[number]; showGrid: boolean; greenPenetration: boolean; - showEnvironment: boolean; showSpacedArmor: boolean; showExternalModules: boolean; showPrimaryArmor: boolean; @@ -35,10 +32,8 @@ export const TankopediaPersistent = createContextualStore(() => wireframe: false, opaque: false, advancedHighlighting: false, - environment: ENVIRONMENTS[0], showGrid: true, greenPenetration: false, - showEnvironment: false, showSpacedArmor: true, showExternalModules: true, showPrimaryArmor: true,