mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-28 21:19:52 +01:00
Compare commits
15
Commits
39745dd475
...
59108d7637
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
59108d7637 | ||
|
|
f85d097c16 | ||
|
|
ed92440b94 | ||
|
|
d41d45abae | ||
|
|
32a7db238b | ||
|
|
2dc23ba09d | ||
|
|
30522bfda0 | ||
|
|
ed31f40876 | ||
|
|
6ad64c9bd9 | ||
|
|
bd7c952478 | ||
|
|
f7180f0e1a | ||
|
|
b0611d7d72 | ||
|
|
244968bbbf | ||
|
|
fd8448b0a6 | ||
|
|
17c54be1c8 |
No files matched your search
@@ -1,5 +1,23 @@
|
||||
import { GameDefinitions } from "../../protos";
|
||||
import {
|
||||
CamouflageDefinitions,
|
||||
ConsumableDefinitions,
|
||||
EquipmentDefinitions,
|
||||
GameDefinitions,
|
||||
MapDefinitions,
|
||||
ModelDefinitions,
|
||||
ProvisionDefinitions,
|
||||
SkillDefinitions,
|
||||
TankDefinitions,
|
||||
} from "@blitzkit/core";
|
||||
|
||||
export abstract class BlitzKitAPI {
|
||||
abstract game(): Promise<GameDefinitions>;
|
||||
abstract skillDefinitions(): Promise<SkillDefinitions>;
|
||||
abstract provisionDefinitions(): Promise<ProvisionDefinitions>;
|
||||
abstract consumableDefinitions(): Promise<ConsumableDefinitions>;
|
||||
abstract equipmentDefinitions(): Promise<EquipmentDefinitions>;
|
||||
abstract mapDefinitions(): Promise<MapDefinitions>;
|
||||
abstract modelDefinitions(): Promise<ModelDefinitions>;
|
||||
abstract camouflageDefinitions(): Promise<CamouflageDefinitions>;
|
||||
abstract tankDefinitions(): Promise<TankDefinitions>;
|
||||
abstract gameDefinitions(): Promise<GameDefinitions>;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,4 +1,4 @@
|
||||
export function assertSecret<Type>(secret?: Type) {
|
||||
export function assertSecret(secret?: string) {
|
||||
if (secret === undefined) throw new Error("Missing secret");
|
||||
return secret;
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
import { assertSecret } from "./assertSecret";
|
||||
|
||||
export function asset(path: string) {
|
||||
return `${assertSecret(import.meta.env.PUBLIC_ASSET_BASE)}/${path}`;
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
import { fetchPB } from '../../protobuf';
|
||||
import { AverageDefinitions } from '../../protos';
|
||||
import { asset } from '../asset';
|
||||
import { staticAsset } from "@blitzkit/core";
|
||||
import { fetchPB } from "../../protobuf";
|
||||
import { AverageDefinitions } from "../../protos";
|
||||
|
||||
export interface AverageDefinitionsManifest {
|
||||
version: 1;
|
||||
@@ -11,13 +11,7 @@ export interface AverageDefinitionsManifest {
|
||||
}
|
||||
|
||||
export async function fetchAverageDefinitions() {
|
||||
const manifestResponse = await fetch(asset('averages/manifest.json'));
|
||||
const manifestJson =
|
||||
(await manifestResponse.json()) as AverageDefinitionsManifest;
|
||||
return await fetchPB(
|
||||
asset(`averages/${manifestJson.latest}.pb`),
|
||||
AverageDefinitions,
|
||||
);
|
||||
return await fetchPB(staticAsset("averages.pb"), AverageDefinitions);
|
||||
}
|
||||
|
||||
export * from './constants';
|
||||
export * from "./constants";
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { CamouflageDefinitions } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchCamouflageDefinitions() {
|
||||
return fetchPB(asset('definitions/camouflages.pb'), CamouflageDefinitions);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { ConsumableDefinitions } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchConsumableDefinitions() {
|
||||
return fetchPB(asset('definitions/consumables.pb'), ConsumableDefinitions);
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { asset } from './asset';
|
||||
import { staticAsset } from "@blitzkit/core";
|
||||
|
||||
export interface DiscoveredIdsDefinitions {
|
||||
time: number;
|
||||
@@ -7,6 +7,6 @@ export interface DiscoveredIdsDefinitions {
|
||||
}
|
||||
|
||||
export async function fetchDiscoveredIdsDefinitions() {
|
||||
const response = await fetch(asset('ids/manifest.json'));
|
||||
const response = await fetch(staticAsset("ids/manifest.json"));
|
||||
return response.json() as Promise<DiscoveredIdsDefinitions>;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { EquipmentDefinitions } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchEquipmentDefinitions() {
|
||||
return fetchPB(asset('definitions/equipment.pb'), EquipmentDefinitions);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { Gallery } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchGallery() {
|
||||
return fetchPB(asset('definitions/gallery.pb'), Gallery);
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
import type { Region } from "../blitz/regions";
|
||||
import { RatingLeaderboard } from "../protos";
|
||||
import { asset } from "./asset";
|
||||
|
||||
const cache: Record<Region, Record<number, RatingLeaderboard>> = {
|
||||
asia: {},
|
||||
eu: {},
|
||||
com: {},
|
||||
};
|
||||
|
||||
export async function getArchivedRatingLeaderboard(
|
||||
region: Region,
|
||||
season: number
|
||||
) {
|
||||
if (!cache[region][season]) {
|
||||
const info = await fetch(asset(`regions/${region}/rating/${season}.pb`))
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then((buffer) => RatingLeaderboard.decode(new Uint8Array(buffer)));
|
||||
cache[region][season] = info;
|
||||
}
|
||||
|
||||
return cache[region][season];
|
||||
}
|
||||
@@ -1,39 +1,27 @@
|
||||
export * from "./api";
|
||||
export * from "./assertSecret";
|
||||
export * from "./asset";
|
||||
export * from "./availableProvisions";
|
||||
export * from "./averageDefinitions";
|
||||
// export * from './camouflageDefinitions';
|
||||
// export * from './checkConsumableProvisionInclusivity';
|
||||
export * from "./coefficient";
|
||||
export * from "./consumableDefinitions";
|
||||
// export * from './context';
|
||||
export * from "./api";
|
||||
export * from "./createDefaultProvisions";
|
||||
export * from "./createDefaultSkills";
|
||||
export * from "./degressiveStat";
|
||||
export * from "./discoveredIdDefinitions";
|
||||
export * from "./emblemURL";
|
||||
export * from "./equipmentDefinitions";
|
||||
export * from "./eventManager";
|
||||
export * from "./getArchivedLatestSeasonNumber";
|
||||
export * from "./sluggify";
|
||||
export * from "./vfs";
|
||||
// export * from './getArchivedRatingInfo';
|
||||
export * from "./getArchivedRatingLeaderboard";
|
||||
// export * from './getArchivedRatingMidnightLeaderboard';
|
||||
export * from "./getTimeDaysAgo";
|
||||
export * from "./isExplosive";
|
||||
export * from "./mapDefinitions";
|
||||
export * from "./modelDefinitions";
|
||||
export * from "./metaSortTank";
|
||||
export * from "./normalizeBoundingBox";
|
||||
// export * from './parseBkni';
|
||||
// export * from './patientFetch';
|
||||
export * from "./patientFetchJSON";
|
||||
export * from "./popularTanks";
|
||||
export * from "./progressiveStat";
|
||||
export * from "./provisionDefinitions";
|
||||
export * from "./resolveDpm";
|
||||
export * from "./resolvePenetrationCoefficient";
|
||||
export * from "./reviews";
|
||||
export * from "./skillDefinitions";
|
||||
export * from "./romanize";
|
||||
export * from "./sluggify";
|
||||
export * from "./staticAsset";
|
||||
export * from "./sum";
|
||||
export * from "./tankDefinitions";
|
||||
export * from "./tankIcon";
|
||||
@@ -41,11 +29,6 @@ export * from "./tankNames";
|
||||
export * from "./unionBoundingBox";
|
||||
export * from "./uniqueGuns";
|
||||
export * from "./unwrapBlitzkitResponse";
|
||||
export * from "./vfs";
|
||||
export * from "./votes";
|
||||
// export * from './withCORSProxy';
|
||||
export * from "./createDefaultProvisions";
|
||||
export * from "./gallery";
|
||||
export * from "./metaSortTank";
|
||||
export * from "./popularTanks";
|
||||
export * from "./romanize";
|
||||
export * from "./youtubers";
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { MapDefinitions } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchMapDefinitions() {
|
||||
return fetchPB(asset('definitions/maps.pb'), MapDefinitions);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { ModelDefinitions } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchModelDefinitions() {
|
||||
return fetchPB(asset('definitions/models.pb'), ModelDefinitions);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { PopularTanks } from '../protos';
|
||||
import { asset } from './asset';
|
||||
import { staticAsset } from "@blitzkit/core";
|
||||
import { fetchPB } from "../protobuf";
|
||||
import { PopularTanks } from "../protos";
|
||||
|
||||
export function fetchPopularTanks() {
|
||||
return fetchPB(asset('definitions/popular-tanks.pb'), PopularTanks);
|
||||
return fetchPB(staticAsset("definitions/popular-tanks.pb"), PopularTanks);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { ProvisionDefinitions } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchProvisionDefinitions() {
|
||||
return fetchPB(asset('definitions/provisions.pb'), ProvisionDefinitions);
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { Reviews } from '../protos';
|
||||
import { asset } from './asset';
|
||||
import { staticAsset } from "@blitzkit/core";
|
||||
import { fetchPB } from "../protobuf";
|
||||
import { Reviews } from "../protos";
|
||||
|
||||
export function fetchReviews() {
|
||||
return fetchPB(asset('definitions/reviews.pb'), Reviews);
|
||||
return fetchPB(staticAsset("definitions/reviews.pb"), Reviews);
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
import { fetchPB } from '../protobuf';
|
||||
import { SkillDefinitions } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export function fetchSkillDefinitions() {
|
||||
return fetchPB(asset('definitions/skills.pb'), SkillDefinitions);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { assertSecret } from "./assertSecret";
|
||||
|
||||
export function staticAsset(path: string) {
|
||||
return `${assertSecret(import.meta.env.PUBLIC_STATIC_ASSET_BASE)}/${path}`;
|
||||
}
|
||||
@@ -1,9 +1 @@
|
||||
import { fetchPB } from '../../protobuf';
|
||||
import { TankDefinitions } from '../../protos';
|
||||
import { asset } from '../asset';
|
||||
|
||||
export function fetchTankDefinitions() {
|
||||
return fetchPB(asset('definitions/tanks.pb'), TankDefinitions);
|
||||
}
|
||||
|
||||
export * from './constants';
|
||||
export * from "./constants";
|
||||
@@ -1,7 +1,5 @@
|
||||
import { asset } from "./asset";
|
||||
|
||||
export const BLITZKIT_TANK_ICON_SIZE = { width: 40 * 16, height: 30 * 16 };
|
||||
|
||||
export function tankIcon(id: number, size: "big" | "small" = "big") {
|
||||
return asset(`icons/tanks/${size}/${id}.webp`);
|
||||
return `/api/tanks/${id}/icons/${size}.webp`;
|
||||
}
|
||||
@@ -1,13 +1,12 @@
|
||||
import { BlitzKitAPI } from "@blitzkit/core";
|
||||
import locales from "@blitzkit/i18n/locales.json";
|
||||
import { deburr } from "lodash-es";
|
||||
import { I18nString } from "../protos";
|
||||
import { fetchCamouflageDefinitions } from "./camouflageDefinitions";
|
||||
import { fetchTankDefinitions } from "./tankDefinitions";
|
||||
|
||||
export async function fetchTankNames() {
|
||||
export async function fetchTankNames(api: BlitzKitAPI) {
|
||||
const [tankDefinitions, camouflageDefinitions] = await Promise.all([
|
||||
fetchTankDefinitions(),
|
||||
fetchCamouflageDefinitions(),
|
||||
api.tankDefinitions(),
|
||||
api.camouflageDefinitions(),
|
||||
]);
|
||||
const tankDefinitionsArray = Object.values(tankDefinitions.tanks);
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
export type BlitzModuleType = {
|
||||
[key in "vehicle" | "engine" | "chassis" | "turret" | "gun"]:
|
||||
| UnlocksInner
|
||||
| UnlocksInner[];
|
||||
};
|
||||
|
||||
interface UnlocksInner {
|
||||
cost: number | string;
|
||||
"#text": number;
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
export interface BlitzStrings {
|
||||
[key: string]: string;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export type BlitzTankFilterDefinitionCategory = "clip";
|
||||
@@ -0,0 +1,33 @@
|
||||
export interface CamouflagesXml {
|
||||
camouflages: Record<
|
||||
string,
|
||||
{
|
||||
id: number;
|
||||
userString: string;
|
||||
description: string;
|
||||
category: string;
|
||||
group: string;
|
||||
kind: string;
|
||||
notInShop: boolean;
|
||||
unlockCostCategory?: string;
|
||||
vehicleFilter: {
|
||||
include?: CamouflagesInclude | CamouflagesInclude[];
|
||||
};
|
||||
script: string[] | string;
|
||||
icon?: string;
|
||||
unlockPremium?: string;
|
||||
unlockQuest?: string;
|
||||
unlockClanLevel?: number;
|
||||
unlockShopBundle?: string;
|
||||
unlockTankRank?: number;
|
||||
}
|
||||
>;
|
||||
}
|
||||
|
||||
type CamouflagesInclude =
|
||||
| {
|
||||
nations?: string;
|
||||
}
|
||||
| {
|
||||
vehicle?: { name?: string; minLevel?: number; maxLevel?: number };
|
||||
};
|
||||
@@ -0,0 +1,7 @@
|
||||
export type CamouflagesYaml = Record<
|
||||
string,
|
||||
{
|
||||
userString?: string;
|
||||
shortUserString?: string;
|
||||
}
|
||||
>;
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface ChassisDefinitionsList {
|
||||
nextAvailableId: number;
|
||||
ids: Record<string, number>;
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
export type CombatRolesYaml = Record<
|
||||
string,
|
||||
{
|
||||
id: number;
|
||||
default_abilities: string[];
|
||||
}
|
||||
>;
|
||||
@@ -0,0 +1,24 @@
|
||||
import { ConsumablesVehicleFilter } from "./consumablesVehicleFilter";
|
||||
|
||||
export interface ConsumablesCommon {
|
||||
[key: string]: {
|
||||
id: number;
|
||||
userString: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
category: string;
|
||||
tags: string;
|
||||
vehicleFilter?: {
|
||||
include: { vehicle: ConsumablesVehicleFilter; nations?: string };
|
||||
exclude?: { vehicle: ConsumablesVehicleFilter; nations?: string };
|
||||
};
|
||||
script: {
|
||||
"#text": string;
|
||||
automatic?: boolean;
|
||||
cooldown: number;
|
||||
duration?: number;
|
||||
shotEffect?: string;
|
||||
bonusValues?: { [key: string]: number };
|
||||
} & Record<string, string>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export type ConsumablesVehicleFilter =
|
||||
| { minLevel: number; maxLevel: number }
|
||||
| { name: string }
|
||||
| { extendedTags: string };
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface EngineDefinitionsList {
|
||||
nextAvailableId: number;
|
||||
ids: Record<string, number>;
|
||||
shared: {
|
||||
[key: string]: {
|
||||
userString: string;
|
||||
level: number;
|
||||
fireStartingChance: number;
|
||||
weight: number;
|
||||
power: number;
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
export interface GunDefinitionsList {
|
||||
nextAvailableId: number;
|
||||
ids: Record<string, number>;
|
||||
shared: {
|
||||
[key: string]: {
|
||||
rotationSpeed: number;
|
||||
weight: number;
|
||||
shotDispersionFactors: {
|
||||
turretRotation: number;
|
||||
afterShot: number;
|
||||
whileGunDamaged: number;
|
||||
};
|
||||
maxAmmo: number;
|
||||
aimingTime: number;
|
||||
shotDispersionRadius: number;
|
||||
userString: string;
|
||||
tags: string;
|
||||
level: number;
|
||||
pitchLimits: string;
|
||||
burst?: { count: number; rate: number };
|
||||
clip?: { count: number; rate: number };
|
||||
shots: {
|
||||
[key: string]: {
|
||||
speed: number;
|
||||
piercingPower: string;
|
||||
maxDistance: number;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -1,4 +1,26 @@
|
||||
export * from "./availableNationsYaml";
|
||||
export * from "./blitzModuleType";
|
||||
export * from "./blitzStrings";
|
||||
export * from "./blitzTankFilterDefinitionCategory";
|
||||
export * from "./camouflagesXml";
|
||||
export * from "./camouflagesYaml";
|
||||
export * from "./chassisDefinitionsList";
|
||||
export * from "./combatRolesYaml";
|
||||
export * from "./consumablesCommon";
|
||||
export * from "./consumablesVehicleFilter";
|
||||
export * from "./engineDefinitionsList";
|
||||
export * from "./glossary";
|
||||
export * from "./gunDefinitionsList";
|
||||
export * from "./mapsYaml";
|
||||
export * from "./optionalDevices";
|
||||
export * from "./optionalDeviceSlots";
|
||||
export * from "./provisionsCommon";
|
||||
export * from "./shellDefinitionsList";
|
||||
export * from "./squadBattleTypeStylesYaml";
|
||||
export * from "./tankmenAvatar";
|
||||
export * from "./tankParameters";
|
||||
export * from "./tanksStats";
|
||||
export * from "./turretDefinitionsList";
|
||||
export * from "./vehicleDefinitionArmor";
|
||||
export * from "./vehicleDefinitionList";
|
||||
export * from "./vehicleDefinitions";
|
||||
@@ -0,0 +1,24 @@
|
||||
export interface MapsYaml {
|
||||
maps: {
|
||||
[key: string]: {
|
||||
id: number;
|
||||
tags?: string;
|
||||
localName: string;
|
||||
avaliableInTrainingRoom: boolean; // lol wg typo
|
||||
spriteFrame: number;
|
||||
supremacyPointsThreshold?: number;
|
||||
availableModes: number[];
|
||||
shadowMapsAvailable?: boolean;
|
||||
assaultRespawnPoints: {
|
||||
allies: MapAlly[];
|
||||
enemies: MapAlly[];
|
||||
};
|
||||
levels?: number[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface MapAlly {
|
||||
respawnNumber: number;
|
||||
points: Array<number[]>;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
export interface OptionalDeviceSlots {
|
||||
presets: {
|
||||
[key: string]: {
|
||||
level0: OptionalDeviceSlotRow;
|
||||
level1: OptionalDeviceSlotRow;
|
||||
level2: OptionalDeviceSlotRow;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
interface OptionalDeviceSlotRow {
|
||||
[key: string]: { device0: string; device1: string };
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
export interface OptionalDevices {
|
||||
[key: string]: {
|
||||
id: number;
|
||||
userString: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
script: unknown;
|
||||
display_params: unknown;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import { ConsumablesVehicleFilter } from "./consumablesVehicleFilter";
|
||||
|
||||
export interface ProvisionsCommon {
|
||||
[key: string]: {
|
||||
id: number;
|
||||
userString: string;
|
||||
description: string;
|
||||
icon: string;
|
||||
category: string;
|
||||
tags: string;
|
||||
vehicleFilter?: {
|
||||
include: { vehicle: ConsumablesVehicleFilter; nations?: string };
|
||||
exclude?: { vehicle: ConsumablesVehicleFilter; nations?: string };
|
||||
};
|
||||
script: {
|
||||
"#text": string;
|
||||
automatic?: boolean;
|
||||
shotEffect?: string;
|
||||
bonusValues?: { [key: string]: number };
|
||||
} & Record<string, string>;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
export type ShellDefinitionsList = Record<
|
||||
string,
|
||||
{
|
||||
id: number;
|
||||
userString: string;
|
||||
icon: string;
|
||||
kind: ShellKind;
|
||||
caliber: number;
|
||||
damage: { armor: number; devices: number };
|
||||
normalizationAngle?: number;
|
||||
ricochetAngle?: number;
|
||||
explosionRadius?: number;
|
||||
}
|
||||
> & {
|
||||
icons: Record<string, string>;
|
||||
};
|
||||
|
||||
export type ShellKind =
|
||||
| "ARMOR_PIERCING"
|
||||
| "ARMOR_PIERCING_CR"
|
||||
| "HIGH_EXPLOSIVE"
|
||||
| "HOLLOW_CHARGE";
|
||||
@@ -0,0 +1,33 @@
|
||||
import { Vector3Tuple } from "three";
|
||||
|
||||
export interface TankParameters {
|
||||
resourcesPath: {
|
||||
smallIconPath: string;
|
||||
bigIconPath: string;
|
||||
blitzModelPath: string;
|
||||
};
|
||||
collision: {
|
||||
[key: string]: {
|
||||
points: Vector3Tuple;
|
||||
bbox: {
|
||||
min: Vector3Tuple;
|
||||
max: Vector3Tuple;
|
||||
};
|
||||
averageThickness?: Record<string, number>;
|
||||
};
|
||||
};
|
||||
maskSlice?: {
|
||||
[key: string]:
|
||||
| {
|
||||
enabled: boolean;
|
||||
planePosition: Vector3Tuple;
|
||||
planeNormal: Vector3Tuple;
|
||||
planeAxis: Vector3Tuple;
|
||||
frustumConeBaseRadius: number;
|
||||
frustumConeAngleDegrees: number;
|
||||
planeSliceMode: number;
|
||||
frustumConeSliceMode: number;
|
||||
}
|
||||
| undefined;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
import { TankClass } from "@blitzkit/core";
|
||||
|
||||
export interface TankmenAvatar {
|
||||
roles: unknown;
|
||||
skillsByClasses: Record<TankClass, string>;
|
||||
skills: {
|
||||
[name: string]: {
|
||||
userString: string;
|
||||
effectDescription: string;
|
||||
tipDescription: string;
|
||||
icon: SkillIcon | SkillIcon[];
|
||||
type: "continuous" | "trigger";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
interface SkillIcon {
|
||||
name: string;
|
||||
state: number;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export interface TurretDefinitionsList {
|
||||
nextAvailableId: number;
|
||||
ids: Record<string, number>;
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
export type VehicleDefinitionArmor = Record<
|
||||
string,
|
||||
number | { vehicleDamageFactor: 0; "#text": number } | number[]
|
||||
>;
|
||||
@@ -0,0 +1,16 @@
|
||||
export interface VehicleDefinitionList {
|
||||
[key: string]: {
|
||||
id: number;
|
||||
userString: string;
|
||||
shortUserString?: string;
|
||||
description: string;
|
||||
price: number | { gold: ""; "#text": number };
|
||||
sellPrice?: { gold: ""; "#text": number };
|
||||
enrichmentPermanentCost: number;
|
||||
notInShop?: boolean;
|
||||
tags: string;
|
||||
level: number;
|
||||
combatRole?: Record<string, string>;
|
||||
configurationModes: string;
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,152 @@
|
||||
import { BlitzModuleType } from "@blitzkit/core";
|
||||
|
||||
export interface VehicleDefinitions {
|
||||
invisibility: {
|
||||
moving: number;
|
||||
still: number;
|
||||
firePenalty: number;
|
||||
};
|
||||
crew: Record<BlitzCrewType, string | string[]>;
|
||||
speedLimits: {
|
||||
forward: number;
|
||||
backward: number;
|
||||
};
|
||||
consumableSlots: number;
|
||||
provisionSlots: number;
|
||||
optDevicePreset: string | string[];
|
||||
hull: {
|
||||
armor: VehicleDefinitionArmor;
|
||||
turretPositions: { turret: string };
|
||||
turretInitialRotation?: { yaw: 0; pitch: 6.5; roll: 0 };
|
||||
maxHealth: number;
|
||||
weight: number;
|
||||
};
|
||||
chassis: {
|
||||
[key: string]: {
|
||||
unlocks: UnlocksListing;
|
||||
weight: number;
|
||||
terrainResistance: string;
|
||||
rotationSpeed: number;
|
||||
userString: string;
|
||||
shotDispersionFactors: {
|
||||
vehicleMovement: number;
|
||||
vehicleRotation: number;
|
||||
};
|
||||
level: number;
|
||||
hullPosition: string;
|
||||
armor: {
|
||||
leftTrack:
|
||||
| number
|
||||
| {
|
||||
chanceToHitByProjectile: number;
|
||||
chanceToHitByExplosion: number;
|
||||
"#text": number;
|
||||
};
|
||||
rightTrack:
|
||||
| number
|
||||
| {
|
||||
chanceToHitByProjectile: number;
|
||||
chanceToHitByExplosion: number;
|
||||
"#text": number;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
engines: {
|
||||
[key: string]: {
|
||||
unlocks: UnlocksListing;
|
||||
};
|
||||
};
|
||||
turrets0: {
|
||||
[key: string]: {
|
||||
unlocks: UnlocksListing;
|
||||
rotationSpeed: number;
|
||||
weight: number;
|
||||
circularVisionRadius: number;
|
||||
maxHealth: number;
|
||||
armor: VehicleDefinitionArmor;
|
||||
userString: string;
|
||||
level: number;
|
||||
yawLimits: string | string[];
|
||||
gunPosition: string | string[];
|
||||
models: { undamaged: string };
|
||||
hitTester: {
|
||||
collisionModel: string;
|
||||
};
|
||||
guns: {
|
||||
[key: string]: {
|
||||
unlocks: UnlocksListing;
|
||||
armor: VehicleDefinitionArmor & {
|
||||
gun?:
|
||||
| number
|
||||
| {
|
||||
chanceToHitByProjectile: number;
|
||||
chanceToHitByExplosion: number;
|
||||
"#text": number;
|
||||
};
|
||||
};
|
||||
invisibilityFactorAtShot: number | number[];
|
||||
reloadTime: number;
|
||||
aimingTime?: number;
|
||||
shotDispersionRadius: number;
|
||||
shotDispersionFactors?: {
|
||||
turretRotation: number;
|
||||
afterShot: number;
|
||||
whileGunDamaged: number;
|
||||
};
|
||||
maxAmmo: number;
|
||||
extraPitchLimits?: {
|
||||
front?: string;
|
||||
back?: string;
|
||||
transition?: number | number[];
|
||||
};
|
||||
pitchLimits?: string | string[];
|
||||
pumpGunMode?: boolean;
|
||||
pumpGunReloadTimes?: string;
|
||||
clip?: { count: number; rate: number };
|
||||
burst?: { count: number; rate: number };
|
||||
models: { undamaged: string };
|
||||
extras?: {
|
||||
trayShell?: {
|
||||
kinds: string;
|
||||
sectors: Record<
|
||||
string,
|
||||
{ id: number; distance: number; factor: number }[]
|
||||
>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
extras?: {
|
||||
armorsStatesController?: {
|
||||
state: [
|
||||
{
|
||||
id: 0;
|
||||
armors: string;
|
||||
type: "default";
|
||||
enabled: true;
|
||||
factorsModifiers: "";
|
||||
default: "";
|
||||
},
|
||||
{
|
||||
id: 1;
|
||||
armors: string;
|
||||
type: "default";
|
||||
enabled: false;
|
||||
factorsModifiers: "";
|
||||
},
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export type BlitzCrewType =
|
||||
| "commander"
|
||||
| "radioman"
|
||||
| "gunner"
|
||||
| "driver"
|
||||
| "loader";
|
||||
|
||||
export type UnlocksListing = BlitzModuleType | undefined;
|
||||
@@ -1,9 +1,11 @@
|
||||
import { assertSecret } from "@blitzkit/core";
|
||||
import { AbstractVFS } from "../core/vfs/abstract";
|
||||
import { LocalVFS } from "../core/vfs/local";
|
||||
import { MixedVFS } from "../core/vfs/mixed";
|
||||
import { SteamVFS } from "../core/vfs/steam";
|
||||
import { ZipVFS } from "../core/vfs/zip";
|
||||
import {
|
||||
AbstractVFS,
|
||||
assertSecret,
|
||||
LocalVFS,
|
||||
MixedVFS,
|
||||
SteamVFS,
|
||||
ZipVFS,
|
||||
} from "@blitzkit/core";
|
||||
|
||||
export const PATCHES_ROOT = "../../temp/patches";
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import sharp from "sharp";
|
||||
import { AssetUploader } from "../core/github/assetUploader";
|
||||
import { parsePackedSpriteRect } from "../core/blitz/parsePackedSpriteRect";
|
||||
import { AssetUploader } from "../core/github/assetUploader";
|
||||
import { vfs } from "./constants";
|
||||
import { ConsumablesCommon, ProvisionsCommon } from "./definitions";
|
||||
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,31 +1,11 @@
|
||||
import { TankClass } from "@blitzkit/core";
|
||||
import sharp from "sharp";
|
||||
import { AssetUploader } from "../core/github/assetUploader";
|
||||
import { vfs } from "./constants";
|
||||
|
||||
interface SkillIcon {
|
||||
name: string;
|
||||
state: number;
|
||||
}
|
||||
|
||||
export interface Avatar {
|
||||
roles: unknown;
|
||||
skillsByClasses: Record<TankClass, string>;
|
||||
skills: {
|
||||
[name: string]: {
|
||||
userString: string;
|
||||
effectDescription: string;
|
||||
tipDescription: string;
|
||||
icon: SkillIcon | SkillIcon[];
|
||||
type: "continuous" | "trigger";
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export async function skillIcons() {
|
||||
console.log("Building skill icons...");
|
||||
|
||||
const avatar = await vfs.xml<{ root: Avatar }>(
|
||||
const avatar = await vfs.xml<{ root: TankmenAvatar }>(
|
||||
`Data/XML/item_defs/tankmen/avatar.xml`,
|
||||
);
|
||||
const uploader = new AssetUploader("skill icons");
|
||||
|
||||
@@ -1,43 +1,10 @@
|
||||
import { NATION_IDS } from "@blitzkit/core";
|
||||
import sharp from "sharp";
|
||||
import type { Vector3Tuple } from "three";
|
||||
import { parsePackedSpriteRect } from "../core/blitz/parsePackedSpriteRect";
|
||||
import { AssetUploader } from "../core/github/assetUploader";
|
||||
import { vfs } from "./constants";
|
||||
import type { 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<string, number>;
|
||||
};
|
||||
};
|
||||
maskSlice?: {
|
||||
[key: string]:
|
||||
| {
|
||||
enabled: boolean;
|
||||
planePosition: Vector3Tuple;
|
||||
planeNormal: Vector3Tuple;
|
||||
planeAxis: Vector3Tuple;
|
||||
frustumConeBaseRadius: number;
|
||||
frustumConeAngleDegrees: number;
|
||||
planeSliceMode: number;
|
||||
frustumConeSliceMode: number;
|
||||
}
|
||||
| undefined;
|
||||
};
|
||||
}
|
||||
|
||||
async function extractPackedTankIcon(packedBuffer: Buffer, context: string) {
|
||||
const texture = sharp(packedBuffer);
|
||||
const spriteRect = parsePackedSpriteRect(packedBuffer);
|
||||
|
||||
@@ -12,7 +12,7 @@ import { tools } from "./src/constants/tools";
|
||||
|
||||
const POSSIBLE_TARGETS = ["app", "web"];
|
||||
|
||||
const target = process.env.PUBLIC_TARGET ;
|
||||
const target = process.env.PUBLIC_TARGET;
|
||||
|
||||
if (!target || !POSSIBLE_TARGETS.includes(target)) {
|
||||
throw new Error("Invalid target");
|
||||
@@ -21,7 +21,11 @@ if (!target || !POSSIBLE_TARGETS.includes(target)) {
|
||||
export default defineConfig({
|
||||
devToolbar: { enabled: false },
|
||||
|
||||
vite: { server: { allowedHosts: [] } },
|
||||
vite: {
|
||||
server: { allowedHosts: [] },
|
||||
esbuild: { target: "es2022" },
|
||||
},
|
||||
|
||||
output: target === "web" ? "static" : "server",
|
||||
site: "https://blitzkit.app",
|
||||
outDir: "../../dist/website",
|
||||
@@ -50,15 +54,15 @@ export default defineConfig({
|
||||
return {
|
||||
name: strings.website.tools[stringId].name,
|
||||
name_localized: wrapper(
|
||||
(strings) => strings.website.tools[stringId].name
|
||||
(strings) => strings.website.tools[stringId].name,
|
||||
),
|
||||
description: strings.website.tools[stringId].description,
|
||||
description_localized: wrapper(
|
||||
(strings) => strings.website.tools[stringId].description
|
||||
(strings) => strings.website.tools[stringId].description,
|
||||
),
|
||||
short_name: strings.website.tools[stringId].name,
|
||||
short_name_localized: wrapper(
|
||||
(strings) => strings.website.tools[stringId].name
|
||||
(strings) => strings.website.tools[stringId].name,
|
||||
),
|
||||
url: `/${tool.id}`,
|
||||
icon: `public/assets/images/tools/${tool.id}.webp`,
|
||||
@@ -68,7 +72,7 @@ export default defineConfig({
|
||||
manifest: {
|
||||
description: strings.website.home.seo_description,
|
||||
description_localized: wrapper(
|
||||
(strings) => strings.website.home.seo_description
|
||||
(strings) => strings.website.home.seo_description,
|
||||
),
|
||||
|
||||
dir: "ltr",
|
||||
|
||||
@@ -11,7 +11,7 @@ export interface Props {
|
||||
locale: string;
|
||||
}
|
||||
|
||||
const gameDefinitions = await api.game();
|
||||
const gameDefinitions = await api.gameDefinitions();
|
||||
const PUBLIC_ASSET_BRANCH = assertSecret(import.meta.env.PUBLIC_BRANCH);
|
||||
const { locale } = Astro.props;
|
||||
const strings = getStrings(locale);
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import {
|
||||
asset,
|
||||
fetchTankDefinitions,
|
||||
TankType,
|
||||
type TankDefinition,
|
||||
} from "@blitzkit/core";
|
||||
import { asset, TankType, type TankDefinition } from "@blitzkit/core";
|
||||
import { Flex, Text, type TextProps } from "@radix-ui/themes";
|
||||
import { uniq } from "lodash-es";
|
||||
import { forwardRef, type ReactNode } from "react";
|
||||
import { api } from "../../core/blitzkit/api";
|
||||
import { useLocale } from "../../hooks/useLocale";
|
||||
import { TankopediaPersistent } from "../../stores/tankopediaPersistent";
|
||||
import { classIcons } from "../ClassIcon";
|
||||
@@ -21,7 +17,7 @@ type TankCardProps = TextProps & {
|
||||
noLink?: boolean;
|
||||
};
|
||||
|
||||
const tankDefinitions = await fetchTankDefinitions();
|
||||
const tankDefinitions = await api.tankDefinitions();
|
||||
|
||||
export const TankCard = forwardRef<HTMLSpanElement, TankCardProps>(
|
||||
(
|
||||
|
||||
@@ -5,7 +5,7 @@ import {
|
||||
type TankDefinition,
|
||||
} from "@blitzkit/core";
|
||||
import { useMemo } from "react";
|
||||
import { awaitableModelDefinitions } from "../../../core/awaitables/modelDefinitions";
|
||||
import { api } from "../../../core/blitzkit/api";
|
||||
import { resolveReload } from "../../../core/blitzkit/resolveReload";
|
||||
import { TankSort } from "../../../stores/tankopediaSort";
|
||||
import { TankCard } from "../../TankCard";
|
||||
@@ -15,7 +15,7 @@ interface TankSearchCardProps {
|
||||
onSelect?: (tank: TankDefinition) => void;
|
||||
}
|
||||
|
||||
const modelDefinitions = await awaitableModelDefinitions;
|
||||
const modelDefinitions = await api.modelDefinitions();
|
||||
|
||||
export function TankSearchCard({ tank, onSelect }: TankSearchCardProps) {
|
||||
const by = TankSort.use((state) => state.by);
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {
|
||||
asset,
|
||||
GunDefinition,
|
||||
ShellType,
|
||||
TANK_CLASSES,
|
||||
@@ -27,10 +26,7 @@ import {
|
||||
} from "@radix-ui/themes";
|
||||
import { times } from "lodash-es";
|
||||
import { Fragment, type ComponentProps, type ReactNode } from "react";
|
||||
import { awaitableConsumableDefinitions } from "../../../core/awaitables/consumableDefinitions";
|
||||
import { awaitableGameDefinitions } from "../../../core/awaitables/gameDefinitions";
|
||||
import { awaitableProvisionDefinitions } from "../../../core/awaitables/provisionDefinitions";
|
||||
import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions";
|
||||
import { api } from "../../../core/blitzkit/api";
|
||||
import { useLocale } from "../../../hooks/useLocale";
|
||||
import { App } from "../../../stores/app";
|
||||
import { TankFilters, type CaseType } from "../../../stores/tankFilters";
|
||||
@@ -43,10 +39,10 @@ import { ResearchedIcon } from "../../ResearchedIcon";
|
||||
import { ScienceIcon } from "../../ScienceIcon";
|
||||
import { ScienceOffIcon } from "../../ScienceOffIcon";
|
||||
|
||||
const gameDefinitions = await awaitableGameDefinitions;
|
||||
const consumableDefinitions = await awaitableConsumableDefinitions;
|
||||
const provisionDefinitions = await awaitableProvisionDefinitions;
|
||||
const tankDefinitions = await awaitableTankDefinitions;
|
||||
const gameDefinitions = await api.gameDefinitions();
|
||||
const consumableDefinitions = await api.consumableDefinitions();
|
||||
const provisionDefinitions = await api.provisionDefinitions();
|
||||
const tankDefinitions = await api.tankDefinitions();
|
||||
|
||||
const gameModeRoleSets: Record<number, Set<number>> = {};
|
||||
|
||||
@@ -313,7 +309,7 @@ function NationsFilter() {
|
||||
width: "1.25em",
|
||||
height: "1.25em",
|
||||
}}
|
||||
src={asset(`flags/circle/${nation}.webp`)}
|
||||
src={`/api/flags/circle/${nation}.webp`}
|
||||
/>
|
||||
))}
|
||||
</Flex>
|
||||
@@ -350,9 +346,7 @@ function NationsFilter() {
|
||||
right="0"
|
||||
mr="-2"
|
||||
style={{
|
||||
backgroundImage: `url(${asset(
|
||||
`flags/scratched/${nation}.webp`,
|
||||
)})`,
|
||||
backgroundImage: `url(${`/api/flags/scratched/${nation}.webp`})`,
|
||||
backgroundSize: "100%",
|
||||
backgroundRepeat: "no-repeat",
|
||||
backgroundPosition: "5rem center",
|
||||
@@ -685,11 +679,9 @@ function IndividualShellFilter({
|
||||
{shells[index] !== null && (
|
||||
<img
|
||||
style={{ width: "1em", height: "1em" }}
|
||||
src={asset(
|
||||
`icons/shells/${shellTypeIcons[shells[index]]}${
|
||||
premium ? "_premium" : ""
|
||||
}.webp`,
|
||||
)}
|
||||
src={`/api/icons/shells/${shellTypeIcons[shells[index]]}${
|
||||
premium ? "_premium" : ""
|
||||
}.webp`}
|
||||
/>
|
||||
)}
|
||||
</IconButton>
|
||||
@@ -720,11 +712,9 @@ function IndividualShellFilter({
|
||||
color={selected ? undefined : "gray"}
|
||||
>
|
||||
<img
|
||||
src={asset(
|
||||
`icons/shells/${shellTypeIcons[shellType]}${
|
||||
premium ? "_premium" : ""
|
||||
}.webp`,
|
||||
)}
|
||||
src={`/api/icons/shells/${shellTypeIcons[shellType]}${
|
||||
premium ? "_premium" : ""
|
||||
}.webp`}
|
||||
style={{ width: "1.25em", height: "1.25em" }}
|
||||
/>
|
||||
|
||||
@@ -893,7 +883,7 @@ function ConsumablesFilter() {
|
||||
height: "1.25em",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={asset(`icons/consumables/${consumable}.webp`)}
|
||||
src={`/api/icons/consumables/${consumable}.webp`}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -938,7 +928,7 @@ function ConsumablesFilter() {
|
||||
height: "1.25em",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={asset(`icons/consumables/${consumable}.webp`)}
|
||||
src={`/api/icons/consumables/${consumable}.webp`}
|
||||
/>
|
||||
|
||||
{unwrap(consumableDefinition.name!)}
|
||||
@@ -987,7 +977,7 @@ function ProvisionsFilter() {
|
||||
height: "1.25em",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={asset(`icons/provisions/${provision}.webp`)}
|
||||
src={`/api/icons/provisions/${provision}.webp`}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -1032,7 +1022,7 @@ function ProvisionsFilter() {
|
||||
height: "1.25em",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={asset(`icons/provisions/${provision}.webp`)}
|
||||
src={`/api/icons/provisions/${provision}.webp`}
|
||||
/>
|
||||
|
||||
{unwrap(provisionDefinition.name!)}
|
||||
@@ -1075,8 +1065,8 @@ function GameModeAbilitiesFilter() {
|
||||
: rawPowers;
|
||||
|
||||
const icons = [
|
||||
...abilities.map((ability) => `icons/consumables/${ability}.webp`),
|
||||
...powers.map((power) => `icons/provisions/${power}.webp`),
|
||||
...abilities.map((ability) => `api/icons/consumables/${ability}.webp`),
|
||||
...powers.map((power) => `api/icons/provisions/${power}.webp`),
|
||||
];
|
||||
|
||||
return (
|
||||
@@ -1094,7 +1084,7 @@ function GameModeAbilitiesFilter() {
|
||||
height: "1.25em",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={asset(icon)}
|
||||
src={icon}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -1161,7 +1151,7 @@ function GameModeAbilitiesFilter() {
|
||||
height: "1.25em",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={asset(`icons/consumables/${consumable}.webp`)}
|
||||
src={`/api/icons/consumables/${consumable}.webp`}
|
||||
/>
|
||||
|
||||
{unwrap(abilityDefinition.name!)}
|
||||
@@ -1210,7 +1200,7 @@ function GameModeAbilitiesFilter() {
|
||||
height: "1.25em",
|
||||
objectFit: "contain",
|
||||
}}
|
||||
src={asset(`icons/provisions/${provision}.webp`)}
|
||||
src={`/api/icons/provisions/${provision}.webp`}
|
||||
/>
|
||||
|
||||
{unwrap(powerDefinition.name!)}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Flex, Separator, Text } from "@radix-ui/themes";
|
||||
import { isEqual } from "lodash-es";
|
||||
import { useMemo } from "react";
|
||||
import { awaitableTankDefinitions } from "../../../core/awaitables/tankDefinitions";
|
||||
import { api } from "../../../core/blitzkit/api";
|
||||
import { useLocale } from "../../../hooks/useLocale";
|
||||
import { TankFilters } from "../../../stores/tankFilters";
|
||||
import { TankopediaPersistent } from "../../../stores/tankopediaPersistent";
|
||||
@@ -9,23 +9,23 @@ import { TankSort } from "../../../stores/tankopediaSort";
|
||||
import { TankCard } from "../../TankCard";
|
||||
import { TankCardWrapper } from "./TankCardWrapper";
|
||||
|
||||
const tankDefinitions = await awaitableTankDefinitions;
|
||||
const tankDefinitions = await api.tankDefinitions();
|
||||
|
||||
export function RecentlyViewed() {
|
||||
const filters = TankFilters.use();
|
||||
// non-reactive because it is a little weird that it updates instantly even before the page loads
|
||||
const recentlyViewed = TankopediaPersistent.state.recentlyViewed.filter(
|
||||
(id) => id in tankDefinitions.tanks
|
||||
(id) => id in tankDefinitions.tanks,
|
||||
);
|
||||
const hasFilters = useMemo(
|
||||
() =>
|
||||
Object.entries(filters).some(([key, value]) => {
|
||||
return !isEqual(
|
||||
value,
|
||||
TankFilters.initial[key as keyof typeof TankFilters.initial]
|
||||
TankFilters.initial[key as keyof typeof TankFilters.initial],
|
||||
);
|
||||
}),
|
||||
[filters]
|
||||
[filters],
|
||||
);
|
||||
const { strings } = useLocale();
|
||||
const by = TankSort.use((state) => state.by);
|
||||
|
||||
@@ -12,10 +12,8 @@ import fuzzysort from "fuzzysort";
|
||||
import { times, uniq } from "lodash-es";
|
||||
import { memo, useEffect, useMemo, useState } from "react";
|
||||
import usePromise from "react-promise-suspense";
|
||||
import { awaitableGameDefinitions } from "../../core/awaitables/gameDefinitions";
|
||||
import { awaitableModelDefinitions } from "../../core/awaitables/modelDefinitions";
|
||||
import { awaitableTankDefinitions } from "../../core/awaitables/tankDefinitions";
|
||||
import { awaitableTankNames } from "../../core/awaitables/tankNames";
|
||||
import { api } from "../../core/blitzkit/api";
|
||||
import { filterTanks } from "../../core/blitzkit/filterTanks";
|
||||
import { resolveReload } from "../../core/blitzkit/resolveReload";
|
||||
import { useLocale } from "../../hooks/useLocale";
|
||||
@@ -47,9 +45,9 @@ const DEFAULT_LOADED_CARDS = 64;
|
||||
|
||||
const [gameDefinitions, modelDefinitions, tankDefinitions, tankNames] =
|
||||
await Promise.all([
|
||||
awaitableGameDefinitions,
|
||||
awaitableModelDefinitions,
|
||||
awaitableTankDefinitions,
|
||||
api.gameDefinitions(),
|
||||
api.modelDefinitions(),
|
||||
api.tankDefinitions(),
|
||||
awaitableTankNames,
|
||||
]);
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
import { fetchConsumableDefinitions } from '@blitzkit/core';
|
||||
|
||||
export const awaitableConsumableDefinitions = fetchConsumableDefinitions();
|
||||
@@ -1,3 +0,0 @@
|
||||
import { fetchGameDefinitions } from '@blitzkit/core';
|
||||
|
||||
export const awaitableGameDefinitions = fetchGameDefinitions();
|
||||
@@ -1,3 +0,0 @@
|
||||
import { fetchModelDefinitions } from '@blitzkit/core';
|
||||
|
||||
export const awaitableModelDefinitions = fetchModelDefinitions();
|
||||
@@ -1,3 +0,0 @@
|
||||
import { fetchProvisionDefinitions } from '@blitzkit/core';
|
||||
|
||||
export const awaitableProvisionDefinitions = fetchProvisionDefinitions();
|
||||
@@ -1,3 +0,0 @@
|
||||
import { fetchTankDefinitions } from '@blitzkit/core';
|
||||
|
||||
export const awaitableTankDefinitions = fetchTankDefinitions();
|
||||
@@ -1,3 +1,4 @@
|
||||
import { fetchTankNames } from '@blitzkit/core';
|
||||
import { fetchTankNames } from "@blitzkit/core";
|
||||
import { api } from "../blitzkit/api";
|
||||
|
||||
export const awaitableTankNames = fetchTankNames();
|
||||
export const awaitableTankNames = fetchTankNames(api);
|
||||
@@ -3,11 +3,12 @@ import {
|
||||
ServerBlitzKitAPI,
|
||||
type BlitzKitAPI,
|
||||
} from "@blitzkit/core";
|
||||
import { vfs } from "./vfs";
|
||||
|
||||
let _api: BlitzKitAPI;
|
||||
|
||||
if (import.meta.env.SSR) {
|
||||
_api = new ServerBlitzKitAPI();
|
||||
_api = await new ServerBlitzKitAPI(vfs).init();
|
||||
} else {
|
||||
_api = new ClientBlitzKitAPI();
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
import { assertSecret } from "@blitzkit/core";
|
||||
import type { GetStaticPaths } from "astro";
|
||||
|
||||
export function chunkedStaticPaths(chunk: string) {
|
||||
return function () {
|
||||
const chunksEnv = assertSecret(import.meta.env.CHUNKS);
|
||||
const chunks = chunksEnv.split(",");
|
||||
|
||||
if (chunksEnv !== "*" && !chunks.includes(chunk)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return [{ params: { [`chunk_${chunk}`]: chunk } }];
|
||||
} satisfies GetStaticPaths;
|
||||
}
|
||||
@@ -1,21 +1,19 @@
|
||||
import type { TankDefinition } from "@blitzkit/core";
|
||||
import { checkConsumableProvisionInclusivity } from "@blitzkit/core/src/blitzkit/checkConsumableProvisionInclusivity";
|
||||
import { times } from "lodash-es";
|
||||
import { awaitableConsumableDefinitions } from "../../core/awaitables/consumableDefinitions";
|
||||
import type { TankFilters } from "../../stores/tankFilters";
|
||||
import { awaitableGameDefinitions } from "../awaitables/gameDefinitions";
|
||||
import { awaitableProvisionDefinitions } from "../awaitables/provisionDefinitions";
|
||||
import { api } from "./api";
|
||||
|
||||
const SHELLS = times(3, (index) => index);
|
||||
|
||||
const consumableDefinitions = await awaitableConsumableDefinitions;
|
||||
const provisionDefinitions = await awaitableProvisionDefinitions;
|
||||
const gameDefinitions = await awaitableGameDefinitions;
|
||||
const consumableDefinitions = await api.consumableDefinitions();
|
||||
const provisionDefinitions = await api.provisionDefinitions();
|
||||
const gameDefinitions = await api.gameDefinitions();
|
||||
|
||||
export async function filterTank(
|
||||
filters: TankFilters,
|
||||
tank: TankDefinition,
|
||||
owned: number[] = []
|
||||
owned: number[] = [],
|
||||
) {
|
||||
return (
|
||||
((filters.showOwned && owned.includes(tank.id)) ||
|
||||
@@ -29,15 +27,15 @@ export async function filterTank(
|
||||
(filters.gunType.length === 0 ||
|
||||
(filters.gunType.includes("regular") &&
|
||||
tank.turrets.some((turret) =>
|
||||
turret.guns.some((gun) => gun.gun_type!.$case === "regular")
|
||||
turret.guns.some((gun) => gun.gun_type!.$case === "regular"),
|
||||
)) ||
|
||||
(filters.gunType.includes("auto_loader") &&
|
||||
tank.turrets.some((turret) =>
|
||||
turret.guns.some((gun) => gun.gun_type!.$case === "auto_loader")
|
||||
turret.guns.some((gun) => gun.gun_type!.$case === "auto_loader"),
|
||||
)) ||
|
||||
(filters.gunType.includes("auto_reloader") &&
|
||||
tank.turrets.some((turret) =>
|
||||
turret.guns.some((gun) => gun.gun_type!.$case === "auto_reloader")
|
||||
turret.guns.some((gun) => gun.gun_type!.$case === "auto_reloader"),
|
||||
))) &&
|
||||
tank.turrets.some((turret) =>
|
||||
turret.guns.some((gun) =>
|
||||
@@ -45,9 +43,9 @@ export async function filterTank(
|
||||
(index) =>
|
||||
filters.shells[index] === null ||
|
||||
gun.shells[index] === undefined ||
|
||||
gun.shells[index].type === filters.shells[index]
|
||||
)
|
||||
)
|
||||
gun.shells[index].type === filters.shells[index],
|
||||
),
|
||||
),
|
||||
) &&
|
||||
(filters.consumables.length === 0 ||
|
||||
filters.consumables.every((consumable) =>
|
||||
@@ -56,10 +54,10 @@ export async function filterTank(
|
||||
checkConsumableProvisionInclusivity(
|
||||
consumableDefinitions.consumables[consumable],
|
||||
tank,
|
||||
gun
|
||||
)
|
||||
)
|
||||
)
|
||||
gun,
|
||||
),
|
||||
),
|
||||
),
|
||||
)) &&
|
||||
(filters.provisions.length === 0 ||
|
||||
filters.provisions.every((provision) =>
|
||||
@@ -68,22 +66,22 @@ export async function filterTank(
|
||||
checkConsumableProvisionInclusivity(
|
||||
provisionDefinitions.provisions[provision],
|
||||
tank,
|
||||
gun
|
||||
)
|
||||
)
|
||||
)
|
||||
gun,
|
||||
),
|
||||
),
|
||||
),
|
||||
)) &&
|
||||
(filters.abilities.length === 0 ||
|
||||
Object.values(tank.roles).some((id) =>
|
||||
gameDefinitions.roles[id as unknown as number].consumables.some(
|
||||
(consumable) => filters.abilities.includes(consumable)
|
||||
)
|
||||
(consumable) => filters.abilities.includes(consumable),
|
||||
),
|
||||
)) &&
|
||||
(filters.powers.length === 0 ||
|
||||
Object.values(tank.roles).some((id) =>
|
||||
gameDefinitions.roles[id as unknown as number].provisions.some(
|
||||
(consumable) => filters.powers.includes(consumable)
|
||||
)
|
||||
(consumable) => filters.powers.includes(consumable),
|
||||
),
|
||||
))
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
import type {
|
||||
GetStaticPathsItem,
|
||||
GetStaticPathsOptions,
|
||||
GetStaticPathsResult,
|
||||
} from "astro";
|
||||
|
||||
type Promisable<T> = T | Promise<T>;
|
||||
|
||||
export function mixStaticPaths<
|
||||
TypeA extends GetStaticPathsItem,
|
||||
TypeB extends GetStaticPathsItem,
|
||||
>(
|
||||
a: (options: GetStaticPathsOptions) => Promisable<TypeA[]>,
|
||||
b: (options: GetStaticPathsOptions) => Promisable<TypeB[]>,
|
||||
) {
|
||||
return async function (options: GetStaticPathsOptions) {
|
||||
const pathsA = await a(options);
|
||||
const pathsB = await b(options);
|
||||
const paths: GetStaticPathsResult = [];
|
||||
|
||||
for (const pathA of pathsA) {
|
||||
for (const pathB of pathsB) {
|
||||
paths.push({
|
||||
params: { ...pathA.params, ...pathB.params },
|
||||
props: { ...pathA.props, ...pathB.props },
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return paths as (TypeA & TypeB)[];
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import { LocalVFS } from "@blitzkit/core";
|
||||
|
||||
export const vfs = new LocalVFS(
|
||||
"/run/media/tresabhi/Windows/Program Files/WindowsApps/7458BE2C.WorldofTanksBlitz_11.19.272.0_x64__x4tje2y229k00",
|
||||
);
|
||||
@@ -0,0 +1,3 @@
|
||||
import { chunkedStaticPaths } from "../../core/blitzkit/chunkedStaticPaths";
|
||||
|
||||
export const getStaticPaths = chunkedStaticPaths("api");
|
||||
@@ -0,0 +1,39 @@
|
||||
import type { APIContext, GetStaticPathsItem } from "astro";
|
||||
import sharp from "sharp";
|
||||
import { mixStaticPaths } from "../../../../core/blitzkit/mixStaticPaths";
|
||||
import { vfs } from "../../../../core/blitzkit/vfs";
|
||||
import { getStaticPaths as _getStaticPaths } from "../../_index";
|
||||
|
||||
export const getStaticPaths = mixStaticPaths(_getStaticPaths, async () => {
|
||||
const paths: GetStaticPathsItem[] = [];
|
||||
|
||||
const circleFiles = await vfs
|
||||
.dir(`Data/Gfx/Lobby/flags`)
|
||||
.then((files) =>
|
||||
files.filter(
|
||||
(flag) =>
|
||||
flag.startsWith("flag_profile-stat_") &&
|
||||
!flag.endsWith("@2x.packed.webp"),
|
||||
),
|
||||
);
|
||||
|
||||
for (const flag of circleFiles) {
|
||||
const path = `Data/Gfx/Lobby/flags/${flag}`;
|
||||
const id = flag.match(/flag_profile-stat_(.+)\.packed\.webp/)![1];
|
||||
|
||||
paths.push({
|
||||
params: { id },
|
||||
props: { path },
|
||||
});
|
||||
}
|
||||
|
||||
return paths;
|
||||
});
|
||||
|
||||
export async function GET({ props }: APIContext<{ path: string }>) {
|
||||
const image = sharp(await vfs.file(props.path));
|
||||
const content = await image.trim({ threshold: 100 }).toBuffer();
|
||||
const bytes = new Uint8Array(content);
|
||||
|
||||
return new Response(bytes);
|
||||
}
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
+3
-3
@@ -1,7 +1,7 @@
|
||||
---
|
||||
import ToolOpenGraph from "../../../components/ToolOpenGraph.astro";
|
||||
import { tools } from "../../../constants/tools";
|
||||
import BaseLayout from "../../../layouts/BaseLayout.astro";
|
||||
import ToolOpenGraph from "../../../../components/ToolOpenGraph.astro";
|
||||
import { tools } from "../../../../constants/tools";
|
||||
import BaseLayout from "../../../../layouts/BaseLayout.astro";
|
||||
import type { getStaticPaths } from "../index.astro";
|
||||
import { Page } from "./_index";
|
||||
|
||||
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
Loaded 100 of 113 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user