rename methods

This commit is contained in:
tresabhi committed 2026-08-30 14:26:08 -05:00
1 parent ec161addab
commit 5f737d940d
111 files changed
+563 -413

No files matched your search

+3
View File
@@ -135,6 +135,7 @@
"radix-ui": "^1.6.7", "radix-ui": "^1.6.7",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"react-error-boundary": "^6.1.3",
"react-promise-suspense": "^0.3.4", "react-promise-suspense": "^0.3.4",
"three": "^0.180.0", "three": "^0.180.0",
"three-stdlib": "^2.36.0", "three-stdlib": "^2.36.0",
@@ -2009,6 +2010,8 @@
"react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="], "react-dom": ["[email protected]", "", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.4" } }, "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ=="],
"react-error-boundary": ["[email protected]", "", { "peerDependencies": { "@types/react": "^18.0.0 || ^19.0.0", "react": "^18.0.0 || ^19.0.0" }, "optionalPeers": ["@types/react"] }, "sha512-GnSKpCohFi2nQmJCWwP8O8wub7zexlePvpsejvQr35vS5RTouS1+utTNOmyc540yw5vyOXnSL1rBWsCQDmkyUA=="],
"react-promise-suspense": ["[email protected]", "", { "dependencies": { "fast-deep-equal": "^2.0.1" } }, "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ=="], "react-promise-suspense": ["[email protected]", "", { "dependencies": { "fast-deep-equal": "^2.0.1" } }, "sha512-I42jl7L3Ze6kZaq+7zXWSunBa3b1on5yfvUW6Eo/3fFOj6dZ5Bqmcd264nJbTK/gn1HjjILAjSwnZbV4RpSaNQ=="],
"react-reconciler": ["[email protected]", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ=="], "react-reconciler": ["[email protected]", "", { "dependencies": { "scheduler": "^0.25.0" }, "peerDependencies": { "react": "^19.0.0" } }, "sha512-7Ob7Z+URmesIsIVRjnLoDGwBEG/tVitidU0nMsqX/eeJaLY89RISO/10ERe0MqmzuKUUB1rmY+h1itMbUHg9BQ=="],
+15 -10
View File
@@ -12,14 +12,19 @@ import {
} from "@blitzkit/core"; } from "@blitzkit/core";
export abstract class BlitzKitAPI { export abstract class BlitzKitAPI {
abstract skillDefinitions(): Promise<SkillDefinitions>; abstract skills(): Promise<SkillDefinitions>;
abstract provisionDefinitions(): Promise<ProvisionDefinitions>; abstract provisions(): Promise<ProvisionDefinitions>;
abstract consumableDefinitions(): Promise<ConsumableDefinitions>; abstract consumables(): Promise<ConsumableDefinitions>;
abstract equipmentDefinitions(): Promise<EquipmentDefinitions>; abstract equipments(): Promise<EquipmentDefinitions>;
abstract mapDefinitions(): Promise<MapDefinitions>; abstract maps(): Promise<MapDefinitions>;
abstract modelDefinitions(): Promise<ModelDefinitions>; abstract models(): Promise<ModelDefinitions>;
abstract camouflageDefinitions(): Promise<CamouflageDefinitions>; abstract camouflages(): Promise<CamouflageDefinitions>;
abstract tankDefinitions(): Promise<TankDefinitions>; abstract tanks(): Promise<TankDefinitions>;
abstract gameDefinitions(): Promise<GameDefinitions>; abstract game(): Promise<GameDefinitions>;
abstract galleryDefinitions(): Promise<Gallery>; abstract gallery(): Promise<Gallery>;
async tank(id: number) {
const tanks = await this.tanks();
return tanks.tanks[id];
}
} }
+10 -10
View File
@@ -15,55 +15,55 @@ import {
import { BlitzKitAPI } from "./base"; import { BlitzKitAPI } from "./base";
export class ClientBlitzKitAPI extends BlitzKitAPI { export class ClientBlitzKitAPI extends BlitzKitAPI {
gameDefinitions() { game() {
return fetchPB(alias("api", "/definitions/game.pb"), GameDefinitions); return fetchPB(alias("api", "/definitions/game.pb"), GameDefinitions);
} }
consumableDefinitions() { consumables() {
return fetchPB( return fetchPB(
alias("api", "/definitions/consumables.pb"), alias("api", "/definitions/consumables.pb"),
ConsumableDefinitions, ConsumableDefinitions,
); );
} }
tankDefinitions() { tanks() {
return fetchPB(alias("api", "/definitions/tanks.pb"), TankDefinitions); return fetchPB(alias("api", "/definitions/tanks.pb"), TankDefinitions);
} }
camouflageDefinitions() { camouflages() {
return fetchPB( return fetchPB(
alias("api", "/definitions/camouflage.pb"), alias("api", "/definitions/camouflage.pb"),
CamouflageDefinitions, CamouflageDefinitions,
); );
} }
provisionDefinitions() { provisions() {
return fetchPB( return fetchPB(
alias("api", "/definitions/provisions.pb"), alias("api", "/definitions/provisions.pb"),
ProvisionDefinitions, ProvisionDefinitions,
); );
} }
modelDefinitions() { models() {
return fetchPB(alias("api", "/definitions/models.pb"), ModelDefinitions); return fetchPB(alias("api", "/definitions/models.pb"), ModelDefinitions);
} }
skillDefinitions() { skills() {
return fetchPB(alias("api", "/definitions/skills.pb"), SkillDefinitions); return fetchPB(alias("api", "/definitions/skills.pb"), SkillDefinitions);
} }
equipmentDefinitions() { equipments() {
return fetchPB( return fetchPB(
alias("api", "/definitions/equipment.pb"), alias("api", "/definitions/equipment.pb"),
EquipmentDefinitions, EquipmentDefinitions,
); );
} }
galleryDefinitions() { gallery() {
return fetchPB(alias("api", "/definitions/gallery.pb"), Gallery); return fetchPB(alias("api", "/definitions/gallery.pb"), Gallery);
} }
mapDefinitions() { maps() {
return fetchPB(alias("api", "/definitions/maps.pb"), MapDefinitions); return fetchPB(alias("api", "/definitions/maps.pb"), MapDefinitions);
} }
} }
+21
View File
@@ -0,0 +1,21 @@
import { AbstractVFS, BlitzKitAPI } from "@blitzkit/core";
export async function createDynamicAPI(vfs: AbstractVFS) {
let _api: BlitzKitAPI;
if (import.meta.env.SSR) {
const { ServerBlitzKitAPI } = await import(
"@blitzkit/core/src/blitzkit/api/server/index"
);
_api = await new ServerBlitzKitAPI(vfs).init();
} else {
const { ClientBlitzKitAPI } = await import(
"@blitzkit/core/src/blitzkit/api/client"
);
_api = new ClientBlitzKitAPI();
}
return _api;
}
+4
View File
@@ -0,0 +1,4 @@
export * from "./base";
export * from "./client";
export * from "./dynamic";
export * from "./server";
@@ -27,11 +27,14 @@ import {
import { AbstractVFS } from "@blitzkit/core/src/blitzkit/vfs/abstract"; import { AbstractVFS } from "@blitzkit/core/src/blitzkit/vfs/abstract";
import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n"; import { SUPPORTED_LOCALE_BLITZ_MAP } from "@blitzkit/i18n";
import locales from "@blitzkit/i18n/locales.json"; import locales from "@blitzkit/i18n/locales.json";
import type { extname, parse } from "node:path";
import { parse as parseYaml } from "yaml"; import { parse as parseYaml } from "yaml";
import { BlitzKitAPI } from "../base"; import { BlitzKitAPI } from "../base";
export abstract class ServerBlitzKitAPI0 extends BlitzKitAPI { export abstract class ServerBlitzKitAPI0 extends BlitzKitAPI {
protected vfs: AbstractVFS; protected vfs: AbstractVFS;
protected parsePath?: typeof parse;
protected extname?: typeof extname;
protected nationSlugDiscriminators = { protected nationSlugDiscriminators = {
china: "cn", china: "cn",
@@ -109,11 +112,18 @@ export abstract class ServerBlitzKitAPI0 extends BlitzKitAPI {
constructor(vfs: AbstractVFS) { constructor(vfs: AbstractVFS) {
super(); super();
this.vfs = vfs; this.vfs = vfs;
} }
async init() { async init() {
console.log("Initializing virtual file system..."); console.log("Initializing virtual file system...");
const path = await import("node:path");
this.extname = path.extname;
this.parsePath = path.parse;
await this.vfs.init(); await this.vfs.init();
console.log("Fetching game data..."); console.log("Fetching game data...");
@@ -1,12 +1,11 @@
import { Avatar, fetchGlossary, Gallery } from "@blitzkit/core"; import { Avatar, fetchGlossary, Gallery } from "@blitzkit/core";
import locales from "@blitzkit/i18n/locales.json"; import locales from "@blitzkit/i18n/locales.json";
import { extname } from "path";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI9 } from "./9_gameDefinitions"; import { ServerBlitzKitAPI9 } from "./9_game";
export abstract class ServerBlitzKitAPI10 extends ServerBlitzKitAPI9 { export abstract class ServerBlitzKitAPI10 extends ServerBlitzKitAPI9 {
@Cache() @Cache()
async galleryDefinitions() { async gallery() {
const avatars: Record<string, { avatar: Avatar; url: string }> = {}; const avatars: Record<string, { avatar: Avatar; url: string }> = {};
await Promise.all( await Promise.all(
@@ -34,7 +33,7 @@ export abstract class ServerBlitzKitAPI10 extends ServerBlitzKitAPI9 {
avatars[key].avatar.name!.locales[supported.locale] = avatars[key].avatar.name!.locales[supported.locale] =
glossaryEntry.title; glossaryEntry.title;
} else { } else {
const extension = extname(glossaryEntry.image_url); const extension = this.extname!(glossaryEntry.image_url);
avatars[key] = { avatars[key] = {
url: glossaryEntry.image_url, url: glossaryEntry.image_url,
@@ -47,7 +47,7 @@ export abstract class ServerBlitzKitAPI1 extends ServerBlitzKitAPI0 {
} }
@Cache() @Cache()
async tankDefinitions() { async tanks() {
const tankDefinitions = TankDefinitions.create(); const tankDefinitions = TankDefinitions.create();
const gameModeNativeNames: Record<string, number> = {}; const gameModeNativeNames: Record<string, number> = {};
@@ -1,10 +1,10 @@
import { CamouflageDefinitions } from "@blitzkit/core"; import { CamouflageDefinitions } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI1 } from "./1_tankDefinitions"; import { ServerBlitzKitAPI1 } from "./1_tanks";
export abstract class ServerBlitzKitAPI2 extends ServerBlitzKitAPI1 { export abstract class ServerBlitzKitAPI2 extends ServerBlitzKitAPI1 {
@Cache() @Cache()
async camouflageDefinitions() { async camouflages() {
const camouflageDefinitions = CamouflageDefinitions.create(); const camouflageDefinitions = CamouflageDefinitions.create();
for (const camoKey in this.camouflagesXml!.root.camouflages) { for (const camoKey in this.camouflagesXml!.root.camouflages) {
@@ -6,7 +6,6 @@ import {
EngineDefinitionsList, EngineDefinitionsList,
GunDefinitionsList, GunDefinitionsList,
ModelDefinitions, ModelDefinitions,
ResearchCost,
TankParameters, TankParameters,
toUniqueId, toUniqueId,
TurretDefinitionsList, TurretDefinitionsList,
@@ -15,10 +14,9 @@ import {
VehicleDefinitionList, VehicleDefinitionList,
VehicleDefinitions, VehicleDefinitions,
} from "@blitzkit/core"; } from "@blitzkit/core";
import { Cache } from "./0_base";
import { ServerBlitzKitAPI2 } from "./2_camouflageDefinitions";
import { parse as parsePath } from "path";
import { Vector3Tuple } from "three"; import { Vector3Tuple } from "three";
import { Cache } from "./0_base";
import { ServerBlitzKitAPI2 } from "./2_camouflages";
export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 { export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
private vector3TupleToBlitzkit(tuple: Vector3Tuple) { private vector3TupleToBlitzkit(tuple: Vector3Tuple) {
@@ -42,7 +40,7 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
} }
@Cache() @Cache()
async modelDefinitions() { async models() {
const modelDefinitions = ModelDefinitions.create(); const modelDefinitions = ModelDefinitions.create();
for (const nation of this.nationsDir!) { for (const nation of this.nationsDir!) {
@@ -65,10 +63,6 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
for (const tankKey in tankList.root) { for (const tankKey in tankList.root) {
if (this.botPattern.test(tankKey)) continue; if (this.botPattern.test(tankKey)) continue;
const gunXps = new Map<number, ResearchCost>();
const turretXps = new Map<number, ResearchCost>();
const engineXps = new Map<number, ResearchCost>();
const trackXps = new Map<number, ResearchCost>();
const tank = tankList.root[tankKey]; const tank = tankList.root[tankKey];
const tankDefinition = await this.vfs.xml<{ root: VehicleDefinitions }>( const tankDefinition = await this.vfs.xml<{ root: VehicleDefinitions }>(
`Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`, `Data/XML/item_defs/vehicles/${nation}/${tankKey}.xml`,
@@ -181,7 +175,7 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
Object.keys(tankDefinition.root.turrets0).forEach((turretKey) => { Object.keys(tankDefinition.root.turrets0).forEach((turretKey) => {
const turret = tankDefinition.root.turrets0[turretKey]; const turret = tankDefinition.root.turrets0[turretKey];
const turretModel = Number( const turretModel = Number(
parsePath(turret.models.undamaged).name.split("_")[1], this.parsePath!(turret.models.undamaged).name.split("_")[1],
); );
const turretId = toUniqueId(nation, turretList.root.ids[turretKey]); const turretId = toUniqueId(nation, turretList.root.ids[turretKey]);
const turretYaw = ( const turretYaw = (
@@ -229,12 +223,16 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
bounding_box: { bounding_box: {
min: this.vector3TupleToBlitzkit( min: this.vector3TupleToBlitzkit(
tankParameters.collision[ tankParameters.collision[
parsePath(turret.hitTester.collisionModel).name.toLowerCase() this.parsePath!(
turret.hitTester.collisionModel,
).name.toLowerCase()
].bbox.min, ].bbox.min,
), ),
max: this.vector3TupleToBlitzkit( max: this.vector3TupleToBlitzkit(
tankParameters.collision[ tankParameters.collision[
parsePath(turret.hitTester.collisionModel).name.toLowerCase() this.parsePath!(
turret.hitTester.collisionModel,
).name.toLowerCase()
].bbox.max, ].bbox.max,
), ),
}, },
@@ -253,7 +251,7 @@ export abstract class ServerBlitzKitAPI3 extends ServerBlitzKitAPI2 {
.split(" ") .split(" ")
.map(Number) as [number, number]; .map(Number) as [number, number];
const gunModel = Number( const gunModel = Number(
parsePath(gun.models.undamaged).name.split("_")[1], this.parsePath!(gun.models.undamaged).name.split("_")[1],
); );
const front = gun.extraPitchLimits?.front const front = gun.extraPitchLimits?.front
? gun.extraPitchLimits.front.split(" ").map(Number) ? gun.extraPitchLimits.front.split(" ").map(Number)
@@ -1,10 +1,10 @@
import { MapDefinitions } from "@blitzkit/core"; import { MapDefinitions } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI3 } from "./3_modelDefinitions"; import { ServerBlitzKitAPI3 } from "./3_models";
export abstract class ServerBlitzKitAPI4 extends ServerBlitzKitAPI3 { export abstract class ServerBlitzKitAPI4 extends ServerBlitzKitAPI3 {
@Cache() @Cache()
async mapDefinitions() { async maps() {
const mapDefinitions = MapDefinitions.create(); const mapDefinitions = MapDefinitions.create();
for (const key in this.mapsYaml!.maps) { for (const key in this.mapsYaml!.maps) {
@@ -1,10 +1,10 @@
import { EquipmentDefinitions, EquipmentSlot } from "@blitzkit/core"; import { EquipmentDefinitions, EquipmentSlot } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI4 } from "./4_mapDefinitions"; import { ServerBlitzKitAPI4 } from "./4_maps";
export abstract class ServerBlitzKitAPI5 extends ServerBlitzKitAPI4 { export abstract class ServerBlitzKitAPI5 extends ServerBlitzKitAPI4 {
@Cache() @Cache()
async equipmentDefinitions() { async equipments() {
const equipmentDefinitions = EquipmentDefinitions.create(); const equipmentDefinitions = EquipmentDefinitions.create();
Object.entries(this.optionalDevices!.root).forEach( Object.entries(this.optionalDevices!.root).forEach(
@@ -4,11 +4,11 @@ import {
ConsumableDefinitions, ConsumableDefinitions,
} from "@blitzkit/core"; } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI5 } from "./5_equipmentDefinitions"; import { ServerBlitzKitAPI5 } from "./5_equipments";
export abstract class ServerBlitzKitAPI6 extends ServerBlitzKitAPI5 { export abstract class ServerBlitzKitAPI6 extends ServerBlitzKitAPI5 {
@Cache() @Cache()
async consumableDefinitions() { async consumables() {
const consumableDefinitions = ConsumableDefinitions.create(); const consumableDefinitions = ConsumableDefinitions.create();
Object.entries(this.consumablesCommon).forEach(([key, consumable]) => { Object.entries(this.consumablesCommon).forEach(([key, consumable]) => {
@@ -4,11 +4,11 @@ import {
ProvisionDefinitions, ProvisionDefinitions,
} from "@blitzkit/core"; } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI6 } from "./6_consumableDefinitions"; import { ServerBlitzKitAPI6 } from "./6_consumables";
export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 { export abstract class ServerBlitzKitAPI7 extends ServerBlitzKitAPI6 {
@Cache() @Cache()
async provisionDefinitions() { async provisions() {
const provisionDefinitions = ProvisionDefinitions.create(); const provisionDefinitions = ProvisionDefinitions.create();
Object.entries(this.provisionsCommon).forEach(([, provision]) => { Object.entries(this.provisionsCommon).forEach(([, provision]) => {
@@ -1,11 +1,11 @@
import { BlitzTankClass, SkillDefinitions } from "@blitzkit/core"; import { BlitzTankClass, SkillDefinitions } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI7 } from "./7_provisionDefinitions"; import { ServerBlitzKitAPI7 } from "./7_provisions";
export abstract class ServerBlitzKitAPI8 extends ServerBlitzKitAPI7 { export abstract class ServerBlitzKitAPI8 extends ServerBlitzKitAPI7 {
@Cache() @Cache()
async skillDefinitions() { async skills() {
const skillDefinitions = SkillDefinitions.create(); const skillDefinitions = SkillDefinitions.create();
for (const tankClass in this.tankmenAvatar!.root.skillsByClasses) { for (const tankClass in this.tankmenAvatar!.root.skillsByClasses) {
@@ -1,11 +1,11 @@
import { AvailableNationsYaml, GameDefinitions } from "@blitzkit/core"; import { AvailableNationsYaml, GameDefinitions } from "@blitzkit/core";
import { Cache } from "./0_base"; import { Cache } from "./0_base";
import { ServerBlitzKitAPI8 } from "./8_skillDefinitions"; import { ServerBlitzKitAPI8 } from "./8_skills";
export abstract class ServerBlitzKitAPI9 extends ServerBlitzKitAPI8 { export abstract class ServerBlitzKitAPI9 extends ServerBlitzKitAPI8 {
@Cache() @Cache()
async gameDefinitions() { async game() {
const gameDefinitions = GameDefinitions.create(); const gameDefinitions = GameDefinitions.create();
const consumableNativeNames: Record<string, number> = {}; const consumableNativeNames: Record<string, number> = {};
@@ -1,3 +1,3 @@
import { ServerBlitzKitAPI10 } from "@blitzkit/core/src/blitzkit/api/server/10_galleryDefinitions"; import { ServerBlitzKitAPI10 } from "./10_avatars";
export class ServerBlitzKitAPI extends ServerBlitzKitAPI10 {} export class ServerBlitzKitAPI extends ServerBlitzKitAPI10 {}
@@ -10,7 +10,7 @@ export interface AverageDefinitionsManifest {
latest: number; latest: number;
} }
export async function fetchAverageDefinitions() { export async function fetchAverage() {
return await fetchPB(staticAsset("averages.pb"), AverageDefinitions); return await fetchPB(staticAsset("averages.pb"), AverageDefinitions);
} }
@@ -6,7 +6,7 @@ export interface DiscoveredIdsDefinitions {
count: number; count: number;
} }
export async function fetchDiscoveredIdsDefinitions() { export async function fetchDiscoveredIds() {
const response = await fetch(staticAsset("ids/manifest.json")); const response = await fetch(staticAsset("ids/manifest.json"));
return response.json() as Promise<DiscoveredIdsDefinitions>; return response.json() as Promise<DiscoveredIdsDefinitions>;
} }
+2
View File
@@ -1,4 +1,5 @@
export * from "./alias"; export * from "./alias";
export * from "./api";
export * from "./assertSecret"; export * from "./assertSecret";
export * from "./availableProvisions"; export * from "./availableProvisions";
export * from "./averageDefinitions"; export * from "./averageDefinitions";
@@ -30,5 +31,6 @@ export * from "./tankNames";
export * from "./unionBoundingBox"; export * from "./unionBoundingBox";
export * from "./uniqueGuns"; export * from "./uniqueGuns";
export * from "./unwrapBlitzkitResponse"; export * from "./unwrapBlitzkitResponse";
export * from "./vfs";
export * from "./votes"; export * from "./votes";
export * from "./youtubers"; export * from "./youtubers";
+2 -2
View File
@@ -5,8 +5,8 @@ import { I18nString } from "../protos";
export async function fetchTankNames(api: BlitzKitAPI) { export async function fetchTankNames(api: BlitzKitAPI) {
const [tankDefinitions, camouflageDefinitions] = await Promise.all([ const [tankDefinitions, camouflageDefinitions] = await Promise.all([
api.tankDefinitions(), api.tanks(),
api.camouflageDefinitions(), api.camouflages(),
]); ]);
const tankDefinitionsArray = Object.values(tankDefinitions.tanks); const tankDefinitionsArray = Object.values(tankDefinitions.tanks);
+5
View File
@@ -0,0 +1,5 @@
export * from "./abstract";
export * from "./local";
export * from "./mixed";
export * from "./steam";
export * from "./zip";
+2 -8
View File
@@ -1,10 +1,4 @@
import { import { asset, Reviews, Video, youtubers } from "@blitzkit/core";
asset,
fetchTankDefinitions,
Reviews,
Video,
youtubers,
} from "@blitzkit/core";
import locales from "@blitzkit/i18n/locales.json"; import locales from "@blitzkit/i18n/locales.json";
import { google } from "googleapis"; import { google } from "googleapis";
import { cloneDeep, uniqBy } from "lodash-es"; import { cloneDeep, uniqBy } from "lodash-es";
@@ -22,7 +16,7 @@ const auth = await google.auth.getClient({
}); });
const youtube = google.youtube({ version: "v3", auth }); const youtube = google.youtube({ version: "v3", auth });
const tankDefinitions = await fetchTankDefinitions(); const tankDefinitions = await fetchTank();
const tanks = Object.values(tankDefinitions.tanks); const tanks = Object.values(tankDefinitions.tanks);
const tanksSanitized = tanks const tanksSanitized = tanks
+1
View File
@@ -43,6 +43,7 @@
"radix-ui": "^1.6.7", "radix-ui": "^1.6.7",
"react": "^19.2.4", "react": "^19.2.4",
"react-dom": "^19.2.4", "react-dom": "^19.2.4",
"react-error-boundary": "^6.1.3",
"react-promise-suspense": "^0.3.4", "react-promise-suspense": "^0.3.4",
"three": "^0.180.0", "three": "^0.180.0",
"three-stdlib": "^2.36.0", "three-stdlib": "^2.36.0",
@@ -1,23 +1,18 @@
import { alias, Avatar } from "@blitzkit/core"; import { alias, Avatar } from "@blitzkit/core";
import { Cross1Icon, DownloadIcon } from "@radix-ui/react-icons"; import { Cross1Icon, DownloadIcon } from "@radix-ui/react-icons";
import {
Dialog,
Flex,
IconButton,
Link,
Skeleton,
Text,
} from "@radix-ui/themes";
import { useRef } from "react"; import { useRef } from "react";
import { useIntersection } from "../../hooks/useIntersection"; import { useIntersection } from "../hooks/useIntersection";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../hooks/useLocale";
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps"; import type { MaybeSkeletonComponentProps } from "../types/maybeSkeletonComponentProps";
import { Flex } from "./Flex";
import { Skeleton } from "./Skeleton";
import { Text } from "./Text";
type GalleryCardProps = MaybeSkeletonComponentProps<{ type GalleryCardProps = MaybeSkeletonComponentProps<{
avatar: Avatar; avatar: Avatar;
}>; }>;
export function GalleryCard(props: GalleryCardProps) { export function AvatarCard(props: GalleryCardProps) {
const src = alias( const src = alias(
"api", "api",
`/gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`, `/gallery/avatars/${!props.skeleton && `${props.avatar.id}${props.avatar.extension}`}`,
@@ -31,17 +26,16 @@ export function GalleryCard(props: GalleryCardProps) {
const content = ( const content = (
<Flex <Flex
direction="column" column
align="center" align="center"
width="6rem"
gap="1" gap="1"
ref={card} ref={card}
style={{ cursor: "pointer" }} style={{ cursor: "pointer" }}
> >
{props.skeleton && ( {props.skeleton && (
<> <>
<Skeleton width="100%" height="4.57rem" /> <Skeleton />
<Skeleton width="100%" height="1em" /> <Skeleton />
</> </>
)} )}
@@ -58,7 +52,7 @@ export function GalleryCard(props: GalleryCardProps) {
alt={unwrap(props.avatar.name!)} alt={unwrap(props.avatar.name!)}
/> />
<Text size="1" align="center" style={{ maxWidth: "100%" }}> <Text size="minor" align="center" style={{ maxWidth: "100%" }}>
{unwrap(props.avatar.name!)} {unwrap(props.avatar.name!)}
</Text> </Text>
</> </>
@@ -1,19 +1,18 @@
import { MagnifyingGlassIcon } from "@radix-ui/react-icons"; import { MagnifyingGlassIcon } from "@radix-ui/react-icons";
import { TextField } from "@radix-ui/themes";
import { useRef } from "react"; import { useRef } from "react";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../../hooks/useLocale";
import { Gallery } from "../../stores/gallery"; import { Gallery } from "../../stores/gallery";
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps"; import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
import { TextField } from "../TextField";
export function GallerySearch({ skeleton }: MaybeSkeletonComponentProps) { export function AvatarsSearch({ skeleton }: MaybeSkeletonComponentProps) {
const input = useRef<HTMLInputElement>(null); const input = useRef<HTMLInputElement>(null);
const { strings } = useLocale(); const { strings } = useLocale();
return ( return (
<TextField.Root <TextField
variant="classic"
disabled={skeleton} disabled={skeleton}
placeholder={strings.website.tools.gallery.search.hint} placeholder={strings.website.tools.avatars.search.hint}
ref={input} ref={input}
onChange={(event) => { onChange={(event) => {
Gallery.mutate((draft) => { Gallery.mutate((draft) => {
@@ -22,9 +21,7 @@ export function GallerySearch({ skeleton }: MaybeSkeletonComponentProps) {
}); });
}} }}
> >
<TextField.Slot> <MagnifyingGlassIcon />
<MagnifyingGlassIcon /> </TextField>
</TextField.Slot>
</TextField.Root>
); );
} }
Whitespace-only changes.
@@ -1,6 +1,5 @@
import locales from "@blitzkit/i18n/locales.json"; import locales from "@blitzkit/i18n/locales.json";
import { literals } from "@blitzkit/i18n/src/literals"; import { literals } from "@blitzkit/i18n/src/literals";
import { Flex, Text } from "@radix-ui/themes";
import fuzzysort from "fuzzysort"; import fuzzysort from "fuzzysort";
import { times } from "lodash-es"; import { times } from "lodash-es";
import { useMemo, useState } from "react"; import { useMemo, useState } from "react";
@@ -8,20 +7,22 @@ import { api } from "../../core/blitzkit/api";
import { useLocale } from "../../hooks/useLocale"; import { useLocale } from "../../hooks/useLocale";
import { Gallery } from "../../stores/gallery"; import { Gallery } from "../../stores/gallery";
import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps"; import type { MaybeSkeletonComponentProps } from "../../types/maybeSkeletonComponentProps";
import { AvatarCard } from "../AvatarCard";
import { Flex } from "../Flex";
import { InlineSkeleton } from "../InlineSkeleton"; import { InlineSkeleton } from "../InlineSkeleton";
import { GalleryCard } from "./Card"; import { Text } from "../Text";
export interface Avatar { export interface Avatar {
name: string; name: string;
id: string; id: string;
} }
const gallery = await api.galleryDefinitions(); const gallery = await api.gallery();
const DEFAULT_LOADED = 42; const DEFAULT_LOADED = 42;
const PREVIEW_COUNT = 28; const PREVIEW_COUNT = 28;
export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) { export function AvatarsList({ skeleton }: MaybeSkeletonComponentProps) {
const search = Gallery.use((state) => state.search); const search = Gallery.use((state) => state.search);
const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED); const [loadedCards, setLoadedCards] = useState(DEFAULT_LOADED);
const { locale, strings } = useLocale(); const { locale, strings } = useLocale();
@@ -48,9 +49,9 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
<> <>
<Text align="center" color="gray"> <Text align="center" color="gray">
{skeleton ? ( {skeleton ? (
<InlineSkeleton width="7rem" /> <InlineSkeleton />
) : ( ) : (
literals(strings.website.tools.gallery.search.results, { literals(strings.website.tools.avatars.search.results, {
count: filtered.length.toLocaleString(locale), count: filtered.length.toLocaleString(locale),
}) })
)} )}
@@ -60,14 +61,14 @@ export function GalleryList({ skeleton }: MaybeSkeletonComponentProps) {
{!skeleton && {!skeleton &&
filtered filtered
.slice(0, loadedCards) .slice(0, loadedCards)
.map((avatar) => <GalleryCard key={avatar.id} avatar={avatar} />)} .map((avatar) => <AvatarCard key={avatar.id} avatar={avatar} />)}
{times( {times(
skeleton skeleton
? DEFAULT_LOADED + PREVIEW_COUNT ? DEFAULT_LOADED + PREVIEW_COUNT
: Math.min(PREVIEW_COUNT, filtered.length - loadedCards), : Math.min(PREVIEW_COUNT, filtered.length - loadedCards),
(index) => ( (index) => (
<GalleryCard <AvatarCard
key={index} key={index}
skeleton skeleton
onIntersection={() => setLoadedCards((state) => state + 2)} onIntersection={() => setLoadedCards((state) => state + 2)}
@@ -0,0 +1,16 @@
.code {
font: inherit;
font-family: var(--font-family-mono);
white-space: pre;
display: inline-block;
&[data-variant="solid"] {
background-color: var(--gray-3);
border-radius: var(--space-3);
padding: var(--space-4);
}
}
@@ -0,0 +1,18 @@
import { classNames } from "../../ui/classNames";
import { Text, type TextProps } from "../Text";
import styles from "./index.module.css";
export interface CodeProps extends TextProps {
lowContrast?: boolean;
variant?: "ghost" | "solid";
}
export function Code({ className, variant = "ghost", ...props }: CodeProps) {
return (
<Text
data-variant={variant}
className={classNames(styles.code, className)}
{...props}
/>
);
}
@@ -39,10 +39,10 @@ const [
consumableDefinitions, consumableDefinitions,
provisionDefinitions, provisionDefinitions,
] = await Promise.all([ ] = await Promise.all([
api.skillDefinitions(), api.skill(),
api.equipmentDefinitions(), api.equipment(),
api.consumableDefinitions(), api.consumables(),
api.provisionDefinitions(), api.provisions(),
]); ]);
export function CompareTable({ stats }: CompareTableProps) { export function CompareTable({ stats }: CompareTableProps) {
@@ -15,7 +15,7 @@ interface ControlsProps {
onAddTankDialogOpenChange: (open: boolean) => void; onAddTankDialogOpenChange: (open: boolean) => void;
} }
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
export function Controls({ export function Controls({
addTankDialogOpen, addTankDialogOpen,
@@ -13,7 +13,7 @@ interface TankControlProps {
slug: string; slug: string;
} }
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
export function TankControl({ index, slug }: TankControlProps) { export function TankControl({ index, slug }: TankControlProps) {
const { locale, strings } = useLocale(); const { locale, strings } = useLocale();
@@ -8,7 +8,7 @@ interface CrewSkillManagerProps {
onChange?: (skillLevels: Record<string, number>) => void; onChange?: (skillLevels: Record<string, number>) => void;
} }
const skillDefinitions = await api.skillDefinitions(); const skillDefinitions = await api.skill();
export function CrewSkillManager({ export function CrewSkillManager({
skillLevels, skillLevels,
@@ -30,7 +30,7 @@ export const compositeStatsKeysOptions = compositeStatsKeys.map((value) => ({
})); }));
const [tankDefinitions, averageDefinitions] = await Promise.all([ const [tankDefinitions, averageDefinitions] = await Promise.all([
api.tankDefinitions(), api.tanks(),
awaitableAverageDefinitions, awaitableAverageDefinitions,
]); ]);
@@ -0,0 +1,55 @@
.error-display {
z-index: 1;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
gap: var(--space-4);
padding: var(--space-4);
box-sizing: border-box;
position: fixed;
top: 0;
left: 0;
width: 100dvw;
height: 100dvh;
text-align: center;
background-color: var(--gray-1);
.info {
display: flex;
align-items: center;
flex-direction: column;
gap: var(--space-3);
}
.error {
text-align: left;
overflow: hidden;
position: relative;
box-sizing: border-box;
max-width: min(100%, var(--page-width));
.cover {
position: absolute;
right: 0;
top: 0;
width: 25%;
height: 100%;
background: linear-gradient(90deg, transparent, var(--gray-1));
}
}
.options {
display: flex;
flex-wrap: wrap;
justify-content: center;
gap: var(--space-3);
}
}
@@ -0,0 +1,84 @@
import { useState, type ReactNode } from "react";
import {
ErrorBoundary,
getErrorMessage,
type FallbackProps,
} from "react-error-boundary";
import { discordLink } from "../../config/socials";
import { Button } from "../Button";
import { Code } from "../Code";
import { Heading } from "../Heading";
import { Link } from "../Link";
import { Text } from "../Text";
import styles from "./index.module.css";
interface Props {
children: ReactNode;
}
export function ErrorWrapper({ children }: Props) {
return (
<ErrorBoundary fallbackRender={(props) => <Fallback {...props} />}>
{children}
</ErrorBoundary>
);
}
function Fallback({ error, resetErrorBoundary }: FallbackProps) {
const [showError, setShowError] = useState(false);
let body: string | undefined;
if (error instanceof Error) {
body = error.stack || getErrorMessage(error);
} else {
body = getErrorMessage(error);
}
body ??= "No error message";
return (
<div className={styles["error-display"]}>
<div className={styles.info}>
<Heading size="3">BlitzKit crashed</Heading>
<Text lowContrast>Sorry about that! You have a couple of options.</Text>
</div>
{showError && (
<Code variant="solid" className={styles.error}>
{body}
<div className={styles.cover} />
</Code>
)}
<div className={styles.options}>
{!showError && (
<Button variant="outline" onClick={() => setShowError(true)}>
View error
</Button>
)}
{showError && (
<Button
variant="outline"
onClick={() => navigator.clipboard.writeText(body)}
>
Copy error
</Button>
)}
<Link href="" underline="never">
<Button variant="outline">Hard reload</Button>
</Link>
<Button variant="outline" onClick={resetErrorBoundary}>
Soft reset
</Button>
<Link href={discordLink} target="_blank" underline="never">
<Button>Discord server</Button>
</Link>
</div>
</div>
);
}
+1 -1
View File
@@ -11,7 +11,7 @@ export interface Props {
locale: string; locale: string;
} }
const gameDefinitions = await api.gameDefinitions(); const gameDefinitions = await api.game();
const environment = assertSecret(import.meta.env.PUBLIC_ENVIRONMENT); const environment = assertSecret(import.meta.env.PUBLIC_ENVIRONMENT);
const { locale } = Astro.props; const { locale } = Astro.props;
const strings = getStrings(locale); const strings = getStrings(locale);
@@ -9,8 +9,8 @@ import { Tankopedia } from "../../stores/tankopedia";
import "./index.css"; import "./index.css";
const [modelDefinitions, provisionDefinitions] = await Promise.all([ const [modelDefinitions, provisionDefinitions] = await Promise.all([
api.modelDefinitions(), api.models(),
api.provisionDefinitions(), api.provisions(),
]); ]);
export function GuessBackground() { export function GuessBackground() {
+1 -1
View File
@@ -40,7 +40,7 @@ const { go } = fuzzysort;
const [tankNames, tankDefinitions] = await Promise.all([ const [tankNames, tankDefinitions] = await Promise.all([
awaitableTankNames, awaitableTankNames,
api.tankDefinitions(), api.tanks(),
]); ]);
const ids = Object.keys(tankDefinitions.tanks); const ids = Object.keys(tankDefinitions.tanks);
@@ -11,7 +11,7 @@ import {
import { TankCard } from "./TankCard"; import { TankCard } from "./TankCard";
const [tankDefinitions, popularTanks] = await Promise.all([ const [tankDefinitions, popularTanks] = await Promise.all([
api.tankDefinitions(), api.tanks(),
awaitablePopularTanks, awaitablePopularTanks,
]); ]);
@@ -12,7 +12,7 @@ import { controlsEnabledEvent } from "../../../core/controlsEnabled";
import { useModel } from "../../../hooks/useModel"; import { useModel } from "../../../hooks/useModel";
import { Mixer } from "../../../stores/mixer"; import { Mixer } from "../../../stores/mixer";
const modelDefinitions = await api.modelDefinitions(); const modelDefinitions = await api.models();
export function Model() { export function Model() {
const canvas = useThree((state) => state.gl.domElement); const canvas = useThree((state) => state.gl.domElement);
@@ -13,7 +13,7 @@ interface ConsumableButtonProps extends TankComponentButtonProps {
cooldown?: number; cooldown?: number;
} }
const consumableDefinitions = await api.consumableDefinitions(); const consumableDefinitions = await api.consumables();
export function ConsumableButton({ export function ConsumableButton({
consumable, consumable,
@@ -8,7 +8,7 @@ interface EquipmentButtonProps extends TankComponentButtonProps {
equipment: number; equipment: number;
} }
const equipmentDefinitions = await api.equipmentDefinitions(); const equipmentDefinitions = await api.equipment();
export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) { export function EquipmentButton({ equipment, ...props }: EquipmentButtonProps) {
const { unwrap } = useLocale(); const { unwrap } = useLocale();
@@ -8,7 +8,7 @@ interface ProvisionButtonProps extends TankComponentButtonProps {
provision: number; provision: number;
} }
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) { export function ProvisionButton({ provision, ...props }: ProvisionButtonProps) {
const { unwrap } = useLocale(); const { unwrap } = useLocale();
@@ -27,7 +27,7 @@ const PREVIEW_COUNT = 10;
const DEFAULT_LOADED_ROWS = 25; const DEFAULT_LOADED_ROWS = 25;
const [tankDefinitions, averageDefinitions] = await Promise.all([ const [tankDefinitions, averageDefinitions] = await Promise.all([
api.tankDefinitions(), api.tanks(),
awaitableAverageDefinitions, awaitableAverageDefinitions,
]); ]);
@@ -22,7 +22,7 @@ import type { MaybeSkeletonComponentProps } from "../types/maybeSkeletonComponen
import { LinkI18n } from "./LinkI18n"; import { LinkI18n } from "./LinkI18n";
import { TankSearchFilters } from "./TankSearchFilters"; import { TankSearchFilters } from "./TankSearchFilters";
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
const POOL_HEIGHT = "16rem"; const POOL_HEIGHT = "16rem";
@@ -14,7 +14,7 @@ interface Props extends PlaylistEntry {
index: number; index: number;
} }
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export const PlaylistTankEntry = memo<Props>( export const PlaylistTankEntry = memo<Props>(
({ id, checked, then, now, index }) => { ({ id, checked, then, now, index }) => {
@@ -9,7 +9,7 @@ interface ProvisionsManagerProps {
onChange?: (provisions: number[]) => void; onChange?: (provisions: number[]) => void;
} }
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
export function ProvisionsManager({ export function ProvisionsManager({
provisions, provisions,
@@ -11,7 +11,7 @@ import { TankCardWrapper } from "../TankCardWrapper";
import { Text } from "../Text"; import { Text } from "../Text";
import styles from "./index.module.css"; import styles from "./index.module.css";
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export function RecentlyViewedTanks() { export function RecentlyViewedTanks() {
const filters = TankFilters.use(); const filters = TankFilters.use();
@@ -21,7 +21,7 @@ type TankCardProps = {
compact?: boolean; compact?: boolean;
}; };
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export const TankCard = (props: MaybeSkeletonComponentProps<TankCardProps>) => { export const TankCard = (props: MaybeSkeletonComponentProps<TankCardProps>) => {
if (props.skeleton) { if (props.skeleton) {
@@ -15,7 +15,7 @@ interface TankSearchCardProps {
onSelect?: (tank: TankDefinition) => void; onSelect?: (tank: TankDefinition) => void;
} }
const modelDefinitions = await api.modelDefinitions(); const modelDefinitions = await api.models();
export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) { export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
const by = TankSort.use((state) => state.by); const by = TankSort.use((state) => state.by);
@@ -45,9 +45,9 @@ export type TankSearchProps = MaybeSkeletonComponentProps & {
const [gameDefinitions, modelDefinitions, tankDefinitions, tankNames] = const [gameDefinitions, modelDefinitions, tankDefinitions, tankNames] =
await Promise.all([ await Promise.all([
api.gameDefinitions(), api.game(),
api.modelDefinitions(), api.models(),
api.tankDefinitions(), api.tanks(),
awaitableTankNames, awaitableTankNames,
]); ]);
@@ -1,19 +1,19 @@
import { import {
alias, alias,
GunDefinition, GunDefinition,
ShellType, ShellType,
TANK_CLASSES, TANK_CLASSES,
TANK_TYPES, TANK_TYPES,
TankType, TankType,
TIER_ROMAN_NUMERALS, TIER_ROMAN_NUMERALS,
} from "@blitzkit/core"; } from "@blitzkit/core";
import { literals } from "@blitzkit/i18n"; import { literals } from "@blitzkit/i18n";
import locales from "@blitzkit/i18n/locales.json"; import locales from "@blitzkit/i18n/locales.json";
import { import {
LockClosedIcon, LockClosedIcon,
LockOpen2Icon, LockOpen2Icon,
ResetIcon, ResetIcon,
TrashIcon, TrashIcon,
} from "@radix-ui/react-icons"; } from "@radix-ui/react-icons";
import { times } from "lodash-es"; import { times } from "lodash-es";
import { Fragment, type ComponentProps, type ReactNode } from "react"; import { Fragment, type ComponentProps, type ReactNode } from "react";
@@ -37,10 +37,10 @@ import { Text } from "../Text";
import { Tooltip } from "../Tooltip"; import { Tooltip } from "../Tooltip";
import styles from "./index.module.css"; import styles from "./index.module.css";
const gameDefinitions = await api.gameDefinitions(); const gameDefinitions = await api.game();
const consumableDefinitions = await api.consumableDefinitions(); const consumableDefinitions = await api.consumables();
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
const gameModeRoleSets: Record<number, Set<number>> = {}; const gameModeRoleSets: Record<number, Set<number>> = {};
@@ -10,7 +10,7 @@ import { AesonPlug } from "../AesonPlug";
import { ExperimentIcon } from "../ExperimentIcon"; import { ExperimentIcon } from "../ExperimentIcon";
import { MAX_RECENTLY_VIEWED } from "../TankSearch/constants"; import { MAX_RECENTLY_VIEWED } from "../TankSearch/constants";
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export function CalloutsSection() { export function CalloutsSection() {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -11,7 +11,7 @@ import { InfoWithDelta } from "./InfoWithDelta";
import { StatsTableWrapper } from "./StatsTableWrapper"; import { StatsTableWrapper } from "./StatsTableWrapper";
import type { StatsAcceptorProps } from "./TraverseVisualizer"; import type { StatsAcceptorProps } from "./TraverseVisualizer";
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
export function Crew({ stats }: StatsAcceptorProps) { export function Crew({ stats }: StatsAcceptorProps) {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -9,7 +9,7 @@ import {
import { Duel } from "../../../../../../../../stores/duel"; import { Duel } from "../../../../../../../../stores/duel";
import { ModelChunk } from "./ModelChunk"; import { ModelChunk } from "./ModelChunk";
const modelDefinitions = await api.modelDefinitions(); const modelDefinitions = await api.models();
export function CanvasContent() { export function CanvasContent() {
const hullWrapper = useRef<Group>(null); const hullWrapper = useRef<Group>(null);
@@ -5,7 +5,7 @@ import { jsxTree } from "../../../../../../../../core/blitzkit/jsxTree";
import { useModel } from "../../../../../../../../hooks/useModel"; import { useModel } from "../../../../../../../../hooks/useModel";
import { Duel } from "../../../../../../../../stores/duel"; import { Duel } from "../../../../../../../../stores/duel";
const modelDefinitions = await api.modelDefinitions(); const modelDefinitions = await api.models();
const surfaceMaterial: Record<Props["only"], MeshBasicMaterial> = { const surfaceMaterial: Record<Props["only"], MeshBasicMaterial> = {
gun: new MeshBasicMaterial({ gun: new MeshBasicMaterial({
@@ -20,7 +20,7 @@ import { FlexibilityCanvas } from "./components/FlexibilityCanvas";
const ANGLE_COEFFICIENT = 1 / 10; const ANGLE_COEFFICIENT = 1 / 10;
const modelDefinition = await api.modelDefinitions(); const modelDefinition = await api.models();
function mag(x: number) { function mag(x: number) {
return (1 / Math.PI) * Math.atan(ANGLE_COEFFICIENT * x) + 1 / 2; return (1 / Math.PI) * Math.atan(ANGLE_COEFFICIENT * x) + 1 / 2;
@@ -37,11 +37,11 @@ const [
modelDefinitions, modelDefinitions,
skillDefinitions, skillDefinitions,
] = await Promise.all([ ] = await Promise.all([
api.tankDefinitions(), api.tanks(),
api.provisionDefinitions(), api.provisions(),
api.equipmentDefinitions(), api.equipment(),
api.modelDefinitions(), api.models(),
api.skillDefinitions(), api.skill(),
]); ]);
export const InfoWithDelta = memo<InfoWithDeltaProps>( export const InfoWithDelta = memo<InfoWithDeltaProps>(
@@ -15,8 +15,8 @@ import { Maneuverability } from "./components/Maneuverability";
import { Survivability } from "./components/Survivability"; import { Survivability } from "./components/Survivability";
const [equipmentDefinitions, provisionDefinitions] = await Promise.all([ const [equipmentDefinitions, provisionDefinitions] = await Promise.all([
api.equipmentDefinitions(), api.equipment(),
api.provisionDefinitions(), api.provisions(),
]); ]);
export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) { export function Characteristics({ skeleton }: MaybeSkeletonComponentProps) {
@@ -15,7 +15,7 @@ import { Duel } from "../../../../stores/duel";
import { ConsumablesManager } from "../../../ConsumablesManager"; import { ConsumablesManager } from "../../../ConsumablesManager";
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
const consumableDefinitions = await api.consumableDefinitions(); const consumableDefinitions = await api.consumables();
export function Consumables() { export function Consumables() {
const protagonist = Duel.use((state) => state.protagonist); const protagonist = Duel.use((state) => state.protagonist);
@@ -5,7 +5,7 @@ import { Duel } from "../../../../stores/duel";
import { EquipmentManager } from "../../../EquipmentManager"; import { EquipmentManager } from "../../../EquipmentManager";
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
const equipmentDefinitions = await api.equipmentDefinitions(); const equipmentDefinitions = await api.equipment();
export function Equipment() { export function Equipment() {
const protagonist = Duel.use((state) => state.protagonist); const protagonist = Duel.use((state) => state.protagonist);
@@ -156,7 +156,7 @@ function ModuleButton({
return <Tooltip content={tooltip}>{node}</Tooltip>; return <Tooltip content={tooltip}>{node}</Tooltip>;
} }
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export function Modules() { export function Modules() {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -6,7 +6,7 @@ import { Duel } from "../../../../stores/duel";
import { ProvisionsManager } from "../../../ProvisionsManager"; import { ProvisionsManager } from "../../../ProvisionsManager";
import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper"; import { ConfigurationChildWrapper } from "./ConfigurationChildWrapper";
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
export function Provisions() { export function Provisions() {
const { tank, gun } = Duel.use((state) => state.protagonist); const { tank, gun } = Duel.use((state) => state.protagonist);
@@ -5,11 +5,7 @@ import { useLocale } from "../../hooks/useLocale";
import { Duel } from "../../stores/duel"; import { Duel } from "../../stores/duel";
const [gameDefinitions, consumableDefinitions, provisionDefinitions] = const [gameDefinitions, consumableDefinitions, provisionDefinitions] =
await Promise.all([ await Promise.all([api.game(), api.consumables(), api.provisions()]);
api.gameDefinitions(),
api.consumableDefinitions(),
api.provisionDefinitions(),
]);
export function GameModeSection() { export function GameModeSection() {
const { unwrap, strings } = useLocale(); const { unwrap, strings } = useLocale();
@@ -21,7 +21,7 @@ const poseDistances: Record<Pose, number> = {
const inspectModeInitialPosition = new Vector3(-8, 2, -13); const inspectModeInitialPosition = new Vector3(-8, 2, -13);
const modelDefinitions = await api.modelDefinitions(); const modelDefinitions = await api.models();
interface ControlsProps { interface ControlsProps {
autoRotate?: boolean; autoRotate?: boolean;
@@ -5,7 +5,7 @@ import { api } from "../../../../../../core/blitzkit/api";
import { modelTransformEvent } from "../../../../../../core/blitzkit/modelTransform"; import { modelTransformEvent } from "../../../../../../core/blitzkit/modelTransform";
import { Duel } from "../../../../../../stores/duel"; import { Duel } from "../../../../../../stores/duel";
const modelDefinitions = await api.modelDefinitions(); const modelDefinitions = await api.models();
export function InitialAligner() { export function InitialAligner() {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
@@ -12,7 +12,7 @@ import { Options } from "./components/Options";
import { TankSandbox } from "./components/TankSandbox"; import { TankSandbox } from "./components/TankSandbox";
import { Title } from "./components/TankSandbox/Title"; import { Title } from "./components/TankSandbox/Title";
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) { export function HeroSection({ skeleton }: MaybeSkeletonComponentProps) {
const equalize = Duel.use((state) => state.equalize); const equalize = Duel.use((state) => state.equalize);
@@ -15,7 +15,7 @@ type NodeProps = MaybeSkeletonComponentProps & {
}; };
const [tankDefinitions, averageDefinitions] = await Promise.all([ const [tankDefinitions, averageDefinitions] = await Promise.all([
api.tankDefinitions(), api.tanks(),
awaitableAverageDefinitions, awaitableAverageDefinitions,
]); ]);
@@ -13,7 +13,7 @@ import { Node } from "./components/Node";
type Line = number[]; type Line = number[];
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export const XP_MULTIPLIERS = [1, 2, 3, 4, 5, 10]; export const XP_MULTIPLIERS = [1, 2, 3, 4, 5, 10];
@@ -10,7 +10,7 @@ interface TierListRowProps {
index: number; index: number;
} }
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export function TierListRow({ index }: TierListRowProps) { export function TierListRow({ index }: TierListRowProps) {
const tanks = TierList.use((state) => state.rows[index].tanks); const tanks = TierList.use((state) => state.rows[index].tanks);
@@ -6,13 +6,13 @@ import { api } from "../../core/blitzkit/api";
import { filterTanks } from "../../core/blitzkit/filterTanks"; import { filterTanks } from "../../core/blitzkit/filterTanks";
import { TankFilters } from "../../stores/tankFilters"; import { TankFilters } from "../../stores/tankFilters";
import { TierList } from "../../stores/tierList"; import { TierList } from "../../stores/tierList";
import { TankCardWrapper } from "../TankCardWrapper";
import { TankCardSkeleton } from "../TankCardSkeleton"; import { TankCardSkeleton } from "../TankCardSkeleton";
import { TankCardWrapper } from "../TankCardWrapper";
import { TierListTile } from "./Tile"; import { TierListTile } from "./Tile";
const [tankDefinitions, gameDefinitions] = await Promise.all([ const [tankDefinitions, gameDefinitions] = await Promise.all([
api.tankDefinitions(), api.tanks(),
api.gameDefinitions(), api.game(),
]); ]);
const tanks = Object.values(tankDefinitions.tanks); const tanks = Object.values(tankDefinitions.tanks);
@@ -3,7 +3,7 @@ import { api } from "../../core/blitzkit/api";
import { generateTierListParams } from "../../core/blitzkit/generateTierListParams"; import { generateTierListParams } from "../../core/blitzkit/generateTierListParams";
import { TierList } from "../../stores/tierList"; import { TierList } from "../../stores/tierList";
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export function URLManager() { export function URLManager() {
const rows = TierList.use((state) => state.rows); const rows = TierList.use((state) => state.rows);
+1
View File
@@ -0,0 +1 @@
export const discordLink = "https://discord.gg/nDt7AjGJQH";
@@ -1,3 +1 @@
import { fetchAverageDefinitions } from '@blitzkit/core'; export const awaitableAverageDefinitions = fetchAverage();
export const awaitableAverageDefinitions = fetchAverageDefinitions();
@@ -1,4 +1 @@
import { fetchDiscoveredIdsDefinitions } from '@blitzkit/core'; export const awaitableDiscoveredIdsDefinitions = fetchDiscoveredIds();
export const awaitableDiscoveredIdsDefinitions =
fetchDiscoveredIdsDefinitions();
+3 -19
View File
@@ -1,20 +1,4 @@
import type { BlitzKitAPI } from "@blitzkit/core/src/blitzkit/api/base"; import { createDynamicAPI } from "@blitzkit/core";
import { vfs } from "./vfs";
let _api: BlitzKitAPI; export const api = await createDynamicAPI(vfs);
if (import.meta.env.SSR) {
const { ServerBlitzKitAPI } = await import(
"@blitzkit/core/src/blitzkit/api/server/index"
);
const { vfs } = await import("./vfs");
_api = await new ServerBlitzKitAPI(vfs).init();
} else {
const { ClientBlitzKitAPI } = await import(
"@blitzkit/core/src/blitzkit/api/client"
);
_api = new ClientBlitzKitAPI();
}
export const api = _api;
@@ -1,7 +1,7 @@
import { api } from "./api"; import { api } from "./api";
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
const modelDefinitions = await api.modelDefinitions(); const modelDefinitions = await api.models();
const tanks = Object.values(tankDefinitions.tanks).filter((tank) => { const tanks = Object.values(tankDefinitions.tanks).filter((tank) => {
const tankModel = modelDefinitions.models[tank.id]; const tankModel = modelDefinitions.models[tank.id];
@@ -6,9 +6,9 @@ import { api } from "./api";
const SHELLS = times(3, (index) => index); const SHELLS = times(3, (index) => index);
const consumableDefinitions = await api.consumableDefinitions(); const consumableDefinitions = await api.consumables();
const provisionDefinitions = await api.provisionDefinitions(); const provisionDefinitions = await api.provisions();
const gameDefinitions = await api.gameDefinitions(); const gameDefinitions = await api.game();
export async function filterTank( export async function filterTank(
filters: TankFilters, filters: TankFilters,
@@ -10,7 +10,7 @@ import { TankFilters } from "../../stores/tankFilters";
import { api } from "./api"; import { api } from "./api";
import { filterTanks } from "./filterTanks"; import { filterTanks } from "./filterTanks";
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
const tanks = Object.values(tankDefinitions.tanks); const tanks = Object.values(tankDefinitions.tanks);
export async function generatePlaylist() { export async function generatePlaylist() {
@@ -1,7 +1,7 @@
import type { EquipmentMatrix } from "../../stores/duel"; import type { EquipmentMatrix } from "../../stores/duel";
import { api } from "./api"; import { api } from "./api";
const equipmentDefinitions = await api.equipmentDefinitions(); const equipmentDefinitions = await api.equipment();
export function hasEquipment( export function hasEquipment(
id: number, id: number,
@@ -0,0 +1,14 @@
import type { ReactNode } from "react";
import { ErrorWrapper } from "../components/ErrorWrapper";
export function withErrorWrapper<Props extends object>(
Component: (props: Props) => ReactNode,
) {
return function (props: Props) {
return (
<ErrorWrapper>
<Component {...props} />
</ErrorWrapper>
);
};
}
+18
View File
@@ -0,0 +1,18 @@
import type { ReactNode } from "react";
import { LocaleProvider } from "../hooks/useLocale";
interface WithLocaleProps {
locale: string;
}
export function withLocale<Props extends object>(
Component: (props: Props) => ReactNode,
) {
return function ({ locale, ...props }: Props & WithLocaleProps) {
return (
<LocaleProvider locale={locale}>
<Component {...(props as Props)} />
</LocaleProvider>
);
};
}
+19
View File
@@ -0,0 +1,19 @@
import { use } from "react";
const cache = new Map<string, Promise<unknown>>();
export function useAwait<Type>(
creator: () => Promise<Type>,
discriminator: string,
) {
let promise;
if (cache.has(discriminator)) {
promise = cache.get(discriminator) as Promise<Type>;
} else {
promise = creator();
cache.set(discriminator, promise);
}
return use(promise);
}
@@ -9,7 +9,7 @@ export enum UseEccentricityMode {
Class, Class,
} }
const tankDefinitions = await api.tankDefinitions(); const tankDefinitions = await api.tanks();
export function useEccentricity(mode: UseEccentricityMode) { export function useEccentricity(mode: UseEccentricityMode) {
const tank = Duel.use((state) => state.protagonist.tank); const tank = Duel.use((state) => state.protagonist.tank);
+1 -1
View File
@@ -2,7 +2,7 @@ import { useMemo } from "react";
import { api } from "../core/blitzkit/api"; import { api } from "../core/blitzkit/api";
import { Duel } from "../stores/duel"; import { Duel } from "../stores/duel";
const equipmentDefinitions = await api.equipmentDefinitions(); const equipmentDefinitions = await api.equipment();
export function useEquipment(id: number, antagonist = false) { export function useEquipment(id: number, antagonist = false) {
const member = Duel.use( const member = Duel.use(
@@ -1,6 +1,6 @@
import { api } from "../core/blitzkit/api"; import { api } from "../core/blitzkit/api";
const equipmentDefinitions = await api.equipmentDefinitions(); const equipmentDefinitions = await api.equipment();
export function useEquipmentPreset(preset: string) { export function useEquipmentPreset(preset: string) {
return equipmentDefinitions.presets[preset]; return equipmentDefinitions.presets[preset];
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.camouflageDefinitions(); const definitions = await api.camouflage();
const bytes = CamouflageDefinitions.encode(definitions).finish(); const bytes = CamouflageDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.consumableDefinitions(); const definitions = await api.consumables();
const bytes = ConsumableDefinitions.encode(definitions).finish(); const bytes = ConsumableDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.equipmentDefinitions(); const definitions = await api.equipment();
const bytes = EquipmentDefinitions.encode(definitions).finish(); const bytes = EquipmentDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.galleryDefinitions(); const definitions = await api.gallery();
const bytes = Gallery.encode(definitions).finish(); const bytes = Gallery.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.gameDefinitions(); const definitions = await api.game();
const bytes = GameDefinitions.encode(definitions).finish(); const bytes = GameDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.mapDefinitions(); const definitions = await api.map();
const bytes = MapDefinitions.encode(definitions).finish(); const bytes = MapDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.modelDefinitions(); const definitions = await api.models();
const bytes = ModelDefinitions.encode(definitions).finish(); const bytes = ModelDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.provisionDefinitions(); const definitions = await api.provisions();
const bytes = ProvisionDefinitions.encode(definitions).finish(); const bytes = ProvisionDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.skillDefinitions(); const definitions = await api.skill();
const bytes = SkillDefinitions.encode(definitions).finish(); const bytes = SkillDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -4,7 +4,7 @@ import { api } from "../../../core/blitzkit/api";
export { getStaticPaths } from "../_index"; export { getStaticPaths } from "../_index";
export async function GET() { export async function GET() {
const definitions = await api.tankDefinitions(); const definitions = await api.tanks();
const bytes = TankDefinitions.encode(definitions).finish(); const bytes = TankDefinitions.encode(definitions).finish();
return new Response(bytes); return new Response(bytes);
@@ -3,7 +3,7 @@ import { mixStaticPaths } from "../../../../core/blitzkit/mixStaticPaths";
import { getStaticPaths as _getStaticPaths } from "../../_index"; import { getStaticPaths as _getStaticPaths } from "../../_index";
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => { export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
const tanks = await api.tankDefinitions(); const tanks = await api.tanks();
return Object.values(tanks.tanks).map((tank) => ({ return Object.values(tanks.tanks).map((tank) => ({
params: { id: tank.id }, params: { id: tank.id },
@@ -1,6 +1,5 @@
import { GalleryList } from "../../../../components/Gallery/List"; import { AvatarsSearch } from "../../../../components/Avatars/Search";
import { GallerySearch } from "../../../../components/Gallery/Search"; import { AvatarsList } from "../../../../components/AvatarsList";
import { PageWrapper } from "../../../../components/PageWrapper";
import { import {
LocaleProvider, LocaleProvider,
type LocaleAcceptorProps, type LocaleAcceptorProps,
@@ -20,9 +19,9 @@ export function Page({
function Content({ skeleton }: MaybeSkeletonComponentProps) { function Content({ skeleton }: MaybeSkeletonComponentProps) {
return ( return (
<PageWrapper maxWidth="80rem" color="gold"> <>
<GallerySearch skeleton={skeleton} /> <AvatarsSearch skeleton={skeleton} />
<GalleryList skeleton={skeleton} /> <AvatarsList skeleton={skeleton} />
</PageWrapper> </>
); );
} }
Loaded 100 of 111 files, more files were not shown because too many files have changed in this diff. Show more