From 69b13fd33a8b18aa62e33547fdc75edea51f597a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tr=C3=A8sAbhi?= <43380238+tresabhi@users.noreply.github.com> Date: Tue, 27 May 2025 12:39:04 -0500 Subject: [PATCH] feat: custom components --- .../core/src/blitz/catalogItemAccessor.ts | 23 +++++++ packages/core/src/blitz/metadataAccessor.ts | 67 ++++++++++++++++++ packages/scripts/src/protos.ts | 68 +++++++++++-------- .../src/components/TestComponent.tsx | 23 +++++-- .../src/core/blitz/unpackedMetadata.ts | 2 +- packages/website-ue/src/hooks/useLocale.tsx | 10 +-- .../src/pages/[...locale]/tanks/index.astro | 13 +++- .../src/pages/api/strings/[locale].json.ts | 14 ---- submodules/blitzkit-closed | 2 +- 9 files changed, 164 insertions(+), 58 deletions(-) delete mode 100644 packages/website-ue/src/pages/api/strings/[locale].json.ts diff --git a/packages/core/src/blitz/catalogItemAccessor.ts b/packages/core/src/blitz/catalogItemAccessor.ts index dde396517..a16759b3e 100644 --- a/packages/core/src/blitz/catalogItemAccessor.ts +++ b/packages/core/src/blitz/catalogItemAccessor.ts @@ -3,9 +3,12 @@ import { Any } from '@protos/google/protobuf/any'; import { MessageFns } from '../protos'; export class CatalogItemAccessor { + public id: string; private components: Record = {}; constructor(item: CatalogItem) { + this.id = item.catalog_id; + for (const component of item.components) { if ( component.value === undefined || @@ -18,6 +21,11 @@ export class CatalogItemAccessor { } } + addComponent(key: string, value: Any) { + this.components[key] = value; + return this; + } + get(Message: MessageFns, component: string) { if (component in this.components) { return Message.decode(this.components[component].value); @@ -25,4 +33,19 @@ export class CatalogItemAccessor { throw new Error(`Unknown component: ${component}`); } + + pack() { + const item: CatalogItem = { catalog_id: this.id, components: [] }; + + for (const componentId in this.components) { + const component = this.components[componentId]; + + item.components.push({ + key: componentId, + value: { type_url: component.type_url, component }, + }); + } + + return item; + } } diff --git a/packages/core/src/blitz/metadataAccessor.ts b/packages/core/src/blitz/metadataAccessor.ts index 3d1ae7889..afb19486d 100644 --- a/packages/core/src/blitz/metadataAccessor.ts +++ b/packages/core/src/blitz/metadataAccessor.ts @@ -1,5 +1,8 @@ import { CatalogItem } from '@protos/blitz_items'; import { Metadata } from '@protos/blitz_metadata'; +import { CatalogItemsComponent } from '@protos/blitz_static_catalog_items_group_component'; +import { BlitzKitAllTankEntities } from '@protos/blitzkit_static_all_tank_entities'; +import { BlitzKitTankCatalogComponent } from '@protos/blitzkit_static_tank_component'; import { CatalogItemAccessor } from './catalogItemAccessor'; export class UnpackedMetadataAccessor { @@ -20,6 +23,70 @@ export class UnpackedMetadataAccessor { throw new Error(`Unknown catalog ID: ${item}`); } + + addCatalogItem(item: CatalogItemAccessor) { + this.items[item.id] = item; + return this; + } + + addCatalogItemWithComponent( + catalogId: string, + componentId: string, + url: string, + value: Uint8Array, + ) { + this.addCatalogItem( + new CatalogItemAccessor({ + catalog_id: catalogId, + components: [], + }).addComponent(componentId, { type_url: url, value }), + ); + } + + getAllTanks() { + return this.get('CatalogItemsGroupEntity.all_tanks').get( + CatalogItemsComponent, + 'catalogItemsGroupComponent', + ); + } + + injectBlitzkit() { + this.injectBlitzKitTankComponents(); + this.injectBlitzKitAllTankEntities(); + + return this; + } + + injectBlitzKitTankComponents() { + for (const item of this.getAllTanks().catalog_items) { + const tank = this.get(item); + const value = BlitzKitTankCatalogComponent.encode({ + id: 'TEST', + set: 'TEST', + }).finish(); + + tank.addComponent('blitzkitTankCatalogComponent', { + type_url: + './blitzkit_static_tank_component.BlitzKitTankCatalogComponent', + value, + }); + } + } + + injectBlitzKitAllTankEntities() { + const allTanksEntities: BlitzKitAllTankEntities = { tanks: [] }; + + for (const item of this.getAllTanks().catalog_items) { + allTanksEntities.tanks.push(this.get(item).pack()); + } + + this.addCatalogItemWithComponent( + 'BlitzKitAllTankEntities.all_tanks', + 'blitzkitAllTankEntitiesComponent', + './blitzkit_static_all_tank_entities.BlitzKitAllTankEntities', + BlitzKitAllTankEntities.encode(allTanksEntities).finish(), + ); + } } export class DiscreteMetadataAccessor { diff --git a/packages/scripts/src/protos.ts b/packages/scripts/src/protos.ts index 4493bb484..de64648f5 100644 --- a/packages/scripts/src/protos.ts +++ b/packages/scripts/src/protos.ts @@ -1,10 +1,9 @@ import { exec as execSync } from 'child_process'; import { existsSync } from 'fs'; import { readdir, rm, writeFile } from 'fs/promises'; +import { chunk } from 'lodash-es'; import { promisify } from 'util'; -const ROOT = 'packages/core/src/protos'; - const exec = promisify(execSync); let executableFileExtension: string; @@ -15,33 +14,42 @@ if (existsSync('node_modules/.bin/protoc-gen-ts_proto.exe')) { executableFileExtension = ''; } -const filesRaw = await readdir(`${ROOT}`); -await Promise.all( - filesRaw.map(async (file) => { - if (!file.endsWith('.proto')) { - await rm(`${ROOT}/${file}`); - } - }), -); +// await compile('packages/core/src/protos'); +await compile('submodules/blitzkit-closed/src/unreal/protos'); -const files = filesRaw.filter((file) => file.endsWith('.proto')); -const args = [ - `--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`, - '--ts_proto_opt=esModuleInterop=true', - '--ts_proto_opt=oneof=unions-value', - '--ts_proto_opt=removeEnumPrefix=true', - '--ts_proto_opt=unrecognizedEnum=false', - '--ts_proto_opt=snakeToCamel=false', - '--ts_proto_out=.', - ...files.map((file) => `${ROOT}/${file}`), -]; +async function compile(root: string) { + const filesRaw = await readdir(root); -await exec(`protoc ${args.join(' ')}`); -await writeFile( - `${ROOT}/index.ts`, - '// @ts-nocheck\n' + - files - .map((file) => file.replace('.proto', '')) - .map((file) => `export * from './${file}.ts';`) - .join('\n'), -); + for (const file of filesRaw) { + if (!file.endsWith('.ts')) continue; + await rm(`${root}/${file}`); + } + + const allFiles = filesRaw.filter((file) => file.endsWith('.proto')); + + for (const files of chunk(allFiles, 32)) { + const args = [ + `-I=${root}`, + `--plugin=./node_modules/.bin/protoc-gen-ts_proto${executableFileExtension}`, + '--ts_proto_opt=esModuleInterop=true', + '--ts_proto_opt=oneof=unions-value', + // '--ts_proto_opt=removeEnumPrefix=true', + '--ts_proto_opt=unrecognizedEnum=false', + '--ts_proto_opt=snakeToCamel=false', + `--ts_proto_out=${root}`, + ...files.map((file) => `${root}/${file}`), + ]; + + await exec(`protoc ${args.join(' ')}`); + } + + await writeFile( + `${root}/index.ts`, + '// @ts-nocheck\n' + + allFiles + .sort() + .map((file) => file.replace('.proto', '')) + .map((file) => `export * from './${file}.ts';`) + .join('\n'), + ); +} diff --git a/packages/website-ue/src/components/TestComponent.tsx b/packages/website-ue/src/components/TestComponent.tsx index de84d7051..6db40081c 100644 --- a/packages/website-ue/src/components/TestComponent.tsx +++ b/packages/website-ue/src/components/TestComponent.tsx @@ -1,9 +1,20 @@ -import { use } from 'react'; +import { + LocaleProvider, + useLocale, + type LocaleAcceptorProps, +} from '../hooks/useLocale'; -export function TestComponent() { - const content = use( - fetch('https://example.com/').then((response) => response.text()), - ); +function Content() { + const { locale, strings } = useLocale(); + const content = JSON.stringify(strings, null, 2); - return
;
+  return {strings.common.units.deg_s};
+}
+
+export function TestComponent({ locale }: LocaleAcceptorProps) {
+  return (
+    
+      
+    
+  );
 }
diff --git a/packages/website-ue/src/core/blitz/unpackedMetadata.ts b/packages/website-ue/src/core/blitz/unpackedMetadata.ts
index 6fd18d1ba..649970ef9 100644
--- a/packages/website-ue/src/core/blitz/unpackedMetadata.ts
+++ b/packages/website-ue/src/core/blitz/unpackedMetadata.ts
@@ -6,4 +6,4 @@ export const unpackedMetadata = new UnpackedMetadataAccessor(
   await requestAutoProxyClient(
     'GetPackedMetadataAsyncRequest',
   ).then(unpackMetadata),
-);
+).injectBlitzkit();
diff --git a/packages/website-ue/src/hooks/useLocale.tsx b/packages/website-ue/src/hooks/useLocale.tsx
index 5420af749..fe7528d97 100644
--- a/packages/website-ue/src/hooks/useLocale.tsx
+++ b/packages/website-ue/src/hooks/useLocale.tsx
@@ -23,15 +23,17 @@ export function LocaleProvider({ locale, children }: LocaleProviderProps) {
   );
 }
 
+const strings = import.meta.glob('../../../i18n/strings/*.json', {
+  import: 'default',
+});
 const cache = new Map>();
 
 function loadLocale(locale: string) {
   if (cache.has(locale)) return cache.get(locale)!;
 
-  const promise = fetch(`/api/strings/${locale}.json`).then((response) => {
-    if (!response.ok) throw new Error('Failed to load locale');
-    return response.json();
-  });
+  const promise = strings[
+    `../../../i18n/strings/${locale}.json`
+  ]() as Promise;
 
   cache.set(locale, promise);
 
diff --git a/packages/website-ue/src/pages/[...locale]/tanks/index.astro b/packages/website-ue/src/pages/[...locale]/tanks/index.astro
index 6b26050fd..197c70125 100644
--- a/packages/website-ue/src/pages/[...locale]/tanks/index.astro
+++ b/packages/website-ue/src/pages/[...locale]/tanks/index.astro
@@ -1,6 +1,6 @@
 ---
 import { CatalogItemsComponent } from '@protos/blitz_static_catalog_items_group_component';
-import { TestComponent } from '../../../components/TestComponent';
+import { BlitzKitAllTankEntities } from '@protos/blitzkit_static_all_tank_entities';
 import { unpackedMetadata } from '../../../core/blitz/unpackedMetadata';
 export { getStaticPaths } from '../index.astro';
 
@@ -9,6 +9,15 @@ const { locale } = Astro.props;
 const allTanks = unpackedMetadata
   .get('CatalogItemsGroupEntity.all_tanks')
   .get(CatalogItemsComponent, 'catalogItemsGroupComponent');
+
+const allTankEntities = unpackedMetadata
+  .get('BlitzKitAllTankEntities.all_tanks')
+  .get(BlitzKitAllTankEntities, 'blitzkitAllTankEntitiesComponent');
 ---
 
-
+
+{JSON.stringify(allTankEntities.tanks.map(tank=>({
+  tank: tank.catalog_id,
+  components: tank.components.map(component=>component.key)
+})), null, 2)}
+
diff --git a/packages/website-ue/src/pages/api/strings/[locale].json.ts b/packages/website-ue/src/pages/api/strings/[locale].json.ts deleted file mode 100644 index ade8aa76c..000000000 --- a/packages/website-ue/src/pages/api/strings/[locale].json.ts +++ /dev/null @@ -1,14 +0,0 @@ -import locales from '@blitzkit/i18n/locales.json' with { type: 'json' }; -import type { APIRoute, GetStaticPaths, GetStaticPathsItem } from 'astro'; -import { getStrings } from 'packages/website-ue/src/core/i18n/getStrings'; - -export const getStaticPaths: GetStaticPaths = () => { - return locales.supported.map( - ({ locale }) => ({ params: { locale } }) satisfies GetStaticPathsItem, - ); -}; - -export const GET: APIRoute = async ({ params, request }) => { - const strings = await getStrings(params.locale!); - return Response.json(strings); -}; diff --git a/submodules/blitzkit-closed b/submodules/blitzkit-closed index 71263548c..57779c5fd 160000 --- a/submodules/blitzkit-closed +++ b/submodules/blitzkit-closed @@ -1 +1 @@ -Subproject commit 71263548cc16aa27cb9b3ab73376f0b53c3f343f +Subproject commit 57779c5fda375f23758e12d58345e23c3f95f9eb