From 4848234264c9c67df642f757d39cc576c9c09f9f Mon Sep 17 00:00:00 2001 From: tresabhi <43380238+tresabhi@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:41:24 -0600 Subject: [PATCH] feat: custom tank icons --- .gitignore | 2 +- bun.lockb | Bin 392663 -> 415505 bytes package.json | 1 + packages/core/package.json | 1 - packages/scripts/package.json | 5 +- packages/scripts/src/buildAssets/tankIcons.ts | 115 +++++------------- .../website/src/components/TankCard/index.tsx | 4 +- .../src/stores/tankopediaPersistent/index.ts | 5 - 8 files changed, 36 insertions(+), 97 deletions(-) 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 fd6f0fc4ea096285d32836c0c24fb0b12cd8cb05..972b90a4624735ade7f0c0dfe8bafa4f7a26ffbc 100644 GIT binary patch delta 25195 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%0Ae(FxR02_X@`a=T>EK z!@5rM3!a>;&y5Jz*ArgM^Elco@nU_CWAvMQup^{vtaBTJch1$3I#=@qIw!&cj zN;l)_3pl5o=|T!K-YCK5osgNi2oVg83{2vKa$DHRxCb?q5(zO5M~AyTdbzIbaaB&b z4=bf6gs6zy9KOiU$$ghrl_>IIwNGMpxIl_nxAi~P+I&{;x?WWYA=F}v&_%wA<+3#@kgT!hFS|#;{tvU1}8iU}BT1oN2ynE9zRWLy0CR(eh=q zkztn3$f^=S`kHUuFV~W@@{_W5+#~I#=BH$0wNHKF271SjsbiiwcZOaEM#jh9X#XJ6 zp~ipSWeh@oZR8sa?P1(JE8yyC1W}?3%dsOHV+{v&XuSnG{+c>@WaokTEtA})=0m4T zc+L^upmP)YzB>us5PHY&g+?82&oLP;GSK)omXG7B=b7T_)fmT4h16sgJ1xs&r{#(o zjS^B45>&}5RbotZXq&L%No^{LHgWOcD)wu;+zQV`e4#dqs(c0iY;2nxInKMPgzy$h z7-IUyMyJFoLZcB^Gd?L6|HVZ_N8;?qeU^*T&CVfQH7YqiJ|;2+k;lK)Vn9%+~4kRE}_QXI7L+-n9n0TQrO&+)fPLk9z`-s_rLTTwf~}{Cf)C2#8MJt z5<-%bRf%zmg!q`T5z#R*Ecc?!qSfDd82N|N3VS+s;b5$Cx(P2E5=19U{=PARfI&U;*wM1LP0pN?sqUy zX^-R?th$TbyqP9WGwf&*oC7Xog>=nR8a?K+M#l2S^|%LK^f`*!rGU%?(v5$7 zL^hv77M_Q>k&6gPN>)TfN5o^CSy^9|sKDJ3D>y5&)W;(+)piO2<-+Wb%PozonnX^O!YuE~tW7H&LtbSX zbsbsAB)KIUeot;9#a%3C$(-)8QH}&RCl1`q#)T{5BQ#T3TqgJJtu?>lUcz%xs@50RA|D4Qx(e5sLXqs+{U!35^}2)g&Wrts}Uw`R0e*yOi0j$?zB@}_n8$67Scr6}GA>F+_7HYH1339Ojlct!_FklT=Aq&s_N=zLF|5I(Z(>|!gv%2wvWs)%)@GIdBd;=zL)G4qJ1wmLbG@S2e^Lr1TT>xx!X6xy z%UU4BI*Rb$S76!Wt6rMC(2%6)FhxXiLU>4W2*qJnu%q|nOseEjCsD`}#nQzb_he)PY@@gCn@>MtOZ1)|xAKn6Ud-c&Q^{NysPjU`MP!g9zt`Z%o zicl3@Ar;&sds0kvoGM8Xf>R843MsL1Ecczv!umg1x>Ed&W0z~nt=s;qbyWM;e3o`r zZd0ERhL6I+*9cWd@SiQQ($~Gg?97jpS66ZafP&iNfy0=t(da2UiR+dkHa5(SLD5QImftNlNVJgzbj_n|CF24bw`o6{+`@knrHk_-c6im Q`B>h+Zr+hka?|Sn2jF#VDgXcg delta 11936 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 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,