mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-24 03:59:50 +02:00
feat: custom components
This commit is contained in:
1 parent
bc6bb4f10e
commit
69b13fd33a
9 files changed
+164
-58
No files matched your search
@@ -3,9 +3,12 @@ import { Any } from '@protos/google/protobuf/any';
|
|||||||
import { MessageFns } from '../protos';
|
import { MessageFns } from '../protos';
|
||||||
|
|
||||||
export class CatalogItemAccessor {
|
export class CatalogItemAccessor {
|
||||||
|
public id: string;
|
||||||
private components: Record<string, Any> = {};
|
private components: Record<string, Any> = {};
|
||||||
|
|
||||||
constructor(item: CatalogItem) {
|
constructor(item: CatalogItem) {
|
||||||
|
this.id = item.catalog_id;
|
||||||
|
|
||||||
for (const component of item.components) {
|
for (const component of item.components) {
|
||||||
if (
|
if (
|
||||||
component.value === undefined ||
|
component.value === undefined ||
|
||||||
@@ -18,6 +21,11 @@ export class CatalogItemAccessor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addComponent(key: string, value: Any) {
|
||||||
|
this.components[key] = value;
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
get<Type>(Message: MessageFns<Type>, component: string) {
|
get<Type>(Message: MessageFns<Type>, component: string) {
|
||||||
if (component in this.components) {
|
if (component in this.components) {
|
||||||
return Message.decode(this.components[component].value);
|
return Message.decode(this.components[component].value);
|
||||||
@@ -25,4 +33,19 @@ export class CatalogItemAccessor {
|
|||||||
|
|
||||||
throw new Error(`Unknown component: ${component}`);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
import { CatalogItem } from '@protos/blitz_items';
|
import { CatalogItem } from '@protos/blitz_items';
|
||||||
import { Metadata } from '@protos/blitz_metadata';
|
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';
|
import { CatalogItemAccessor } from './catalogItemAccessor';
|
||||||
|
|
||||||
export class UnpackedMetadataAccessor {
|
export class UnpackedMetadataAccessor {
|
||||||
@@ -20,6 +23,70 @@ export class UnpackedMetadataAccessor {
|
|||||||
|
|
||||||
throw new Error(`Unknown catalog ID: ${item}`);
|
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 {
|
export class DiscreteMetadataAccessor {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
import { exec as execSync } from 'child_process';
|
import { exec as execSync } from 'child_process';
|
||||||
import { existsSync } from 'fs';
|
import { existsSync } from 'fs';
|
||||||
import { readdir, rm, writeFile } from 'fs/promises';
|
import { readdir, rm, writeFile } from 'fs/promises';
|
||||||
|
import { chunk } from 'lodash-es';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
|
||||||
const ROOT = 'packages/core/src/protos';
|
|
||||||
|
|
||||||
const exec = promisify(execSync);
|
const exec = promisify(execSync);
|
||||||
|
|
||||||
let executableFileExtension: string;
|
let executableFileExtension: string;
|
||||||
@@ -15,33 +14,42 @@ if (existsSync('node_modules/.bin/protoc-gen-ts_proto.exe')) {
|
|||||||
executableFileExtension = '';
|
executableFileExtension = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
const filesRaw = await readdir(`${ROOT}`);
|
// await compile('packages/core/src/protos');
|
||||||
await Promise.all(
|
await compile('submodules/blitzkit-closed/src/unreal/protos');
|
||||||
filesRaw.map(async (file) => {
|
|
||||||
if (!file.endsWith('.proto')) {
|
|
||||||
await rm(`${ROOT}/${file}`);
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
const files = filesRaw.filter((file) => file.endsWith('.proto'));
|
async function compile(root: string) {
|
||||||
const args = [
|
const filesRaw = await readdir(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=.',
|
|
||||||
...files.map((file) => `${ROOT}/${file}`),
|
|
||||||
];
|
|
||||||
|
|
||||||
await exec(`protoc ${args.join(' ')}`);
|
for (const file of filesRaw) {
|
||||||
await writeFile(
|
if (!file.endsWith('.ts')) continue;
|
||||||
`${ROOT}/index.ts`,
|
await rm(`${root}/${file}`);
|
||||||
'// @ts-nocheck\n' +
|
}
|
||||||
files
|
|
||||||
.map((file) => file.replace('.proto', ''))
|
const allFiles = filesRaw.filter((file) => file.endsWith('.proto'));
|
||||||
.map((file) => `export * from './${file}.ts';`)
|
|
||||||
.join('\n'),
|
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'),
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -1,9 +1,20 @@
|
|||||||
import { use } from 'react';
|
import {
|
||||||
|
LocaleProvider,
|
||||||
|
useLocale,
|
||||||
|
type LocaleAcceptorProps,
|
||||||
|
} from '../hooks/useLocale';
|
||||||
|
|
||||||
export function TestComponent() {
|
function Content() {
|
||||||
const content = use(
|
const { locale, strings } = useLocale();
|
||||||
fetch('https://example.com/').then((response) => response.text()),
|
const content = JSON.stringify(strings, null, 2);
|
||||||
);
|
|
||||||
|
|
||||||
return <pre children={content} />;
|
return <span>{strings.common.units.deg_s}</span>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function TestComponent({ locale }: LocaleAcceptorProps) {
|
||||||
|
return (
|
||||||
|
<LocaleProvider locale={locale}>
|
||||||
|
<Content />
|
||||||
|
</LocaleProvider>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
@@ -6,4 +6,4 @@ export const unpackedMetadata = new UnpackedMetadataAccessor(
|
|||||||
await requestAutoProxyClient<GetPackedMetadataAsyncResponse>(
|
await requestAutoProxyClient<GetPackedMetadataAsyncResponse>(
|
||||||
'GetPackedMetadataAsyncRequest',
|
'GetPackedMetadataAsyncRequest',
|
||||||
).then(unpackMetadata),
|
).then(unpackMetadata),
|
||||||
);
|
).injectBlitzkit();
|
||||||
@@ -23,15 +23,17 @@ export function LocaleProvider({ locale, children }: LocaleProviderProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const strings = import.meta.glob('../../../i18n/strings/*.json', {
|
||||||
|
import: 'default',
|
||||||
|
});
|
||||||
const cache = new Map<string, Promise<BlitzKitStrings>>();
|
const cache = new Map<string, Promise<BlitzKitStrings>>();
|
||||||
|
|
||||||
function loadLocale(locale: string) {
|
function loadLocale(locale: string) {
|
||||||
if (cache.has(locale)) return cache.get(locale)!;
|
if (cache.has(locale)) return cache.get(locale)!;
|
||||||
|
|
||||||
const promise = fetch(`/api/strings/${locale}.json`).then((response) => {
|
const promise = strings[
|
||||||
if (!response.ok) throw new Error('Failed to load locale');
|
`../../../i18n/strings/${locale}.json`
|
||||||
return response.json();
|
]() as Promise<BlitzKitStrings>;
|
||||||
});
|
|
||||||
|
|
||||||
cache.set(locale, promise);
|
cache.set(locale, promise);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
import { CatalogItemsComponent } from '@protos/blitz_static_catalog_items_group_component';
|
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';
|
import { unpackedMetadata } from '../../../core/blitz/unpackedMetadata';
|
||||||
export { getStaticPaths } from '../index.astro';
|
export { getStaticPaths } from '../index.astro';
|
||||||
|
|
||||||
@@ -9,6 +9,15 @@ const { locale } = Astro.props;
|
|||||||
const allTanks = unpackedMetadata
|
const allTanks = unpackedMetadata
|
||||||
.get('CatalogItemsGroupEntity.all_tanks')
|
.get('CatalogItemsGroupEntity.all_tanks')
|
||||||
.get(CatalogItemsComponent, 'catalogItemsGroupComponent');
|
.get(CatalogItemsComponent, 'catalogItemsGroupComponent');
|
||||||
|
|
||||||
|
const allTankEntities = unpackedMetadata
|
||||||
|
.get('BlitzKitAllTankEntities.all_tanks')
|
||||||
|
.get(BlitzKitAllTankEntities, 'blitzkitAllTankEntitiesComponent');
|
||||||
---
|
---
|
||||||
|
|
||||||
<TestComponent />
|
<pre>
|
||||||
|
{JSON.stringify(allTankEntities.tanks.map(tank=>({
|
||||||
|
tank: tank.catalog_id,
|
||||||
|
components: tank.components.map(component=>component.key)
|
||||||
|
})), null, 2)}
|
||||||
|
</pre>
|
||||||
@@ -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);
|
|
||||||
};
|
|
||||||
Submodule submodules/blitzkit-closed updated: 71263548cc...57779c5fda.
Reference in new issue
Block a user