mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: transition to protobug
This commit is contained in:
1 parent
45dc99e1ce
commit
370ef2df65
16 files changed
+105
-387
No files matched your search
@@ -22,3 +22,4 @@ depots
|
||||
public/sitemap*
|
||||
/firebase.json
|
||||
target
|
||||
packages/core/src/protos/generated/*
|
||||
@@ -1,41 +1,6 @@
|
||||
import { decodeProtobuf } from '../../protobuf/decodeProtobuf';
|
||||
import { BlitzkitStats } from '../../statistics';
|
||||
import { AverageDefinitions } from '../../protos';
|
||||
import { asset } from '../asset';
|
||||
|
||||
export interface AverageDefinitionsEntry {
|
||||
mu: BlitzkitStats;
|
||||
sigma: BlitzkitStats;
|
||||
r: BlitzkitStats;
|
||||
samples: Samples;
|
||||
}
|
||||
|
||||
export interface AverageDefinitionsEntrySubPartial {
|
||||
mu: Partial<BlitzkitStats>;
|
||||
sigma: Partial<BlitzkitStats>;
|
||||
r: Partial<BlitzkitStats>;
|
||||
samples: Samples;
|
||||
}
|
||||
|
||||
export interface AverageDefinitionsEntryWithId extends AverageDefinitionsEntry {
|
||||
id: number;
|
||||
}
|
||||
|
||||
export interface AverageDefinitions {
|
||||
averages: Record<number, AverageDefinitionsEntry>;
|
||||
samples: Samples;
|
||||
time: number;
|
||||
}
|
||||
|
||||
export interface Samples {
|
||||
d_1: number;
|
||||
d_7: number;
|
||||
d_30: number;
|
||||
d_60: number;
|
||||
d_90: number;
|
||||
d_120: number;
|
||||
total: number;
|
||||
}
|
||||
|
||||
export interface AverageDefinitionsManifest {
|
||||
version: 1;
|
||||
/**
|
||||
@@ -44,30 +9,18 @@ export interface AverageDefinitionsManifest {
|
||||
latest: number;
|
||||
}
|
||||
|
||||
export const averageDefinitions = fetch(asset('averages/manifest.json'), {
|
||||
cache: 'no-store',
|
||||
})
|
||||
.then((response) => response.json() as Promise<AverageDefinitionsManifest>)
|
||||
.then((manifest) => fetch(asset(`averages/${manifest.latest}.pb`)))
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then((buffer) =>
|
||||
decodeProtobuf<AverageDefinitions>(
|
||||
'average_definitions',
|
||||
'blitzkit.AverageDefinitions',
|
||||
new Uint8Array(buffer),
|
||||
),
|
||||
export async function fetchAverageDefinitions() {
|
||||
const manifestResponse = await fetch(asset('averages/manifest.json'));
|
||||
const manifestJson =
|
||||
(await manifestResponse.json()) as AverageDefinitionsManifest;
|
||||
const averageDefinitionsResponse = await fetch(
|
||||
asset(`averages/${manifestJson.latest}.pb`),
|
||||
);
|
||||
const averageDefinitionsBuffer =
|
||||
await averageDefinitionsResponse.arrayBuffer();
|
||||
const averageDefinitionsArray = new Uint8Array(averageDefinitionsBuffer);
|
||||
|
||||
export const averageDefinitionsArray = averageDefinitions.then((data) =>
|
||||
Object.entries(data.averages)
|
||||
.map(
|
||||
([key, value]) =>
|
||||
({
|
||||
id: Number(key),
|
||||
...(value as AverageDefinitionsEntry),
|
||||
}) satisfies AverageDefinitionsEntryWithId,
|
||||
)
|
||||
.filter((tank) => tank.mu.battles > 0),
|
||||
);
|
||||
return AverageDefinitions.deserializeBinary(averageDefinitionsArray);
|
||||
}
|
||||
|
||||
export * from './constants';
|
||||
@@ -1,26 +1,10 @@
|
||||
import { decodeProtobuf } from '../protobuf';
|
||||
import { Reviews } from '../protos';
|
||||
import { asset } from './asset';
|
||||
|
||||
export interface Reviews {
|
||||
reviews: Record<number, Review>;
|
||||
}
|
||||
export async function fetchReviews() {
|
||||
const response = await fetch(asset('definitions/reviews.pb'));
|
||||
const buffer = await response.arrayBuffer();
|
||||
const array = new Uint8Array(buffer);
|
||||
|
||||
interface Review {
|
||||
last_updated: number;
|
||||
videos?: Video[];
|
||||
return Reviews.deserializeBinary(array);
|
||||
}
|
||||
|
||||
export interface Video {
|
||||
id: string;
|
||||
author: string;
|
||||
}
|
||||
|
||||
export const reviews = fetch(asset('definitions/reviews.pb'))
|
||||
.then((response) => response.arrayBuffer())
|
||||
.then((buffer) =>
|
||||
decodeProtobuf<Reviews>(
|
||||
'reviews',
|
||||
'blitzkit.Reviews',
|
||||
new Uint8Array(buffer),
|
||||
),
|
||||
);
|
||||
@@ -1,224 +1,12 @@
|
||||
import { Vector2Tuple } from 'three';
|
||||
import { TankDefinitions } from '../../protos';
|
||||
import { asset } from '../asset';
|
||||
import { fetchCdonLz4 } from '../fetchCdonLz4';
|
||||
|
||||
export enum TankClass {
|
||||
Unspecified,
|
||||
Light,
|
||||
Medium,
|
||||
Heavy,
|
||||
TankDestroyer,
|
||||
}
|
||||
export enum TankType {
|
||||
Unspecified,
|
||||
Researchable,
|
||||
Premium,
|
||||
Collector,
|
||||
}
|
||||
export async function fetchTankDefinitions() {
|
||||
const response = await fetch(asset('definitions/tanks.pb'));
|
||||
const buffer = await response.arrayBuffer();
|
||||
const array = new Uint8Array(buffer);
|
||||
|
||||
export enum ShellType {
|
||||
Unspecified,
|
||||
AP,
|
||||
APCR,
|
||||
HEAT,
|
||||
HE,
|
||||
}
|
||||
|
||||
export enum CrewType {
|
||||
Unspecified,
|
||||
Commander,
|
||||
Radioman,
|
||||
Gunner,
|
||||
Driver,
|
||||
Loader,
|
||||
}
|
||||
|
||||
export type TankDefinitions = Record<number, TankDefinition>;
|
||||
export enum ModuleType {
|
||||
Unspecified,
|
||||
Vehicle,
|
||||
Engine,
|
||||
Tracks,
|
||||
Turret,
|
||||
Gun,
|
||||
}
|
||||
|
||||
export interface Unlock {
|
||||
type: ModuleType;
|
||||
id: number;
|
||||
cost: {
|
||||
// string being the season coins
|
||||
type: 'xp' | string;
|
||||
value: number;
|
||||
};
|
||||
}
|
||||
export interface Crew {
|
||||
type: CrewType;
|
||||
count?: number;
|
||||
substitute?: CrewType[];
|
||||
}
|
||||
export type ModuleDefinition =
|
||||
| TrackDefinition
|
||||
| EngineDefinition
|
||||
| TurretDefinition
|
||||
| GunDefinition;
|
||||
export interface TankDefinition {
|
||||
id: number;
|
||||
roles: Record<number, number>;
|
||||
description?: string;
|
||||
fixed_camouflage: boolean;
|
||||
camouflages: number[];
|
||||
ancestors: number[];
|
||||
successors: number[];
|
||||
crew: Crew[];
|
||||
health: number;
|
||||
nation: string;
|
||||
name: string;
|
||||
nameFull?: string;
|
||||
type: TankType;
|
||||
max_consumables: number;
|
||||
max_provisions: number;
|
||||
tier: Tier;
|
||||
class: TankClass;
|
||||
testing: boolean;
|
||||
deprecated: boolean;
|
||||
turrets: TurretDefinition[];
|
||||
engines: EngineDefinition[];
|
||||
tracks: TrackDefinition[];
|
||||
price: TankPrice;
|
||||
xp?: number;
|
||||
speed_forwards: number;
|
||||
speed_backwards: number;
|
||||
camouflage_still: number;
|
||||
camouflage_moving: number;
|
||||
camouflage_onFire: number;
|
||||
equipment_preset: string;
|
||||
weight: number;
|
||||
}
|
||||
export interface TrackDefinition {
|
||||
id: number;
|
||||
tier: Tier;
|
||||
name: string;
|
||||
weight: number;
|
||||
traverse_speed: number;
|
||||
xp?: number;
|
||||
dispersion_move: number;
|
||||
dispersion_traverse: number;
|
||||
resistance_hard: number;
|
||||
resistance_medium: number;
|
||||
resistance_soft: number;
|
||||
unlocks?: Unlock[];
|
||||
}
|
||||
export interface EngineDefinition {
|
||||
id: number;
|
||||
name: string;
|
||||
xp?: number;
|
||||
tier: Tier;
|
||||
fire_chance: number;
|
||||
power: number;
|
||||
weight: number;
|
||||
unlocks?: Unlock[];
|
||||
}
|
||||
export type TankPrice = {
|
||||
type: TankPriceType;
|
||||
value: number;
|
||||
};
|
||||
enum TankPriceType {
|
||||
Unspecified,
|
||||
Credits,
|
||||
Gold,
|
||||
}
|
||||
export interface TurretDefinition {
|
||||
health: number;
|
||||
view_range: number;
|
||||
traverse_speed: number;
|
||||
xp?: number;
|
||||
id: number;
|
||||
name: string;
|
||||
tier: Tier;
|
||||
guns: GunDefinition[];
|
||||
weight: number;
|
||||
unlocks?: Unlock[];
|
||||
}
|
||||
export type GunDefinition =
|
||||
| GunDefinitionRegular
|
||||
| GunDefinitionAutoLoader
|
||||
| GunDefinitionAutoReloader;
|
||||
interface GunDefinitionBase {
|
||||
rotation_speed: number;
|
||||
xp?: number;
|
||||
weight: number;
|
||||
id: number;
|
||||
name: string;
|
||||
tier: Tier;
|
||||
shells: ShellDefinition[];
|
||||
camouflage_loss: number;
|
||||
aim_time: number;
|
||||
dispersion_base: number;
|
||||
dispersion_traverse: number;
|
||||
dispersion_shot: number;
|
||||
dispersion_damaged: number;
|
||||
unlocks?: Unlock[];
|
||||
}
|
||||
interface GunDefinitionRegular {
|
||||
gun: GunDefinitionBase;
|
||||
regular: GunDefinitionRegularProperties;
|
||||
}
|
||||
interface GunDefinitionRegularProperties {
|
||||
reload: number;
|
||||
}
|
||||
interface GunDefinitionAutoLoader {
|
||||
gun: GunDefinitionBase;
|
||||
auto_loader: GunDefinitionAutoLoaderProperties;
|
||||
}
|
||||
interface GunDefinitionAutoLoaderProperties {
|
||||
reload: number;
|
||||
intra_clip: number;
|
||||
count: number;
|
||||
}
|
||||
interface GunDefinitionAutoReloader {
|
||||
gun: GunDefinitionBase;
|
||||
auto_reloader: GunDefinitionAutoReloaderProperties;
|
||||
}
|
||||
interface GunDefinitionAutoReloaderProperties {
|
||||
reload: number[];
|
||||
intraClip: number;
|
||||
count: number;
|
||||
}
|
||||
export interface ShellDefinition {
|
||||
id: number;
|
||||
name: string;
|
||||
velocity: number;
|
||||
armor_damage: number;
|
||||
module_damage: number;
|
||||
caliber: number;
|
||||
icon: string;
|
||||
penetration: number | Vector2Tuple;
|
||||
type: ShellType;
|
||||
normalization?: number;
|
||||
ricochet?: number;
|
||||
explosion_radius?: number;
|
||||
}
|
||||
|
||||
export const tankDefinitions = fetchCdonLz4<TankDefinitions>(
|
||||
asset('definitions/tanks.cdon.lz4'),
|
||||
);
|
||||
|
||||
export const tankDefinitionsArray = tankDefinitions.then((tanks) =>
|
||||
Object.values(tanks),
|
||||
);
|
||||
export enum Tier {
|
||||
Unspecified,
|
||||
I,
|
||||
II,
|
||||
III,
|
||||
IV,
|
||||
V,
|
||||
VI,
|
||||
VII,
|
||||
VIII,
|
||||
IX,
|
||||
X,
|
||||
return TankDefinitions.deserializeBinary(array);
|
||||
}
|
||||
|
||||
export * from './constants';
|
||||
@@ -1,11 +1,11 @@
|
||||
export * from './blitz';
|
||||
export * from './blitzkit';
|
||||
export * from './protos';
|
||||
// export * from './blitzstars';
|
||||
// export * from './databases';
|
||||
export * from './imgur';
|
||||
export * from './math';
|
||||
export * from './patreon';
|
||||
// export * from './protobuf';
|
||||
export * from './statistics';
|
||||
// export * from './streams';
|
||||
// export * from './types';
|
||||
@@ -1,9 +0,0 @@
|
||||
import { lookupProtobufType, ProtoSource } from './lookupProtobufType';
|
||||
|
||||
export function decodeProtobuf<Type>(
|
||||
source: ProtoSource,
|
||||
type: string,
|
||||
data: Uint8Array,
|
||||
) {
|
||||
return lookupProtobufType(source, type).decode(data).toJSON() as Type;
|
||||
}
|
||||
@@ -1,14 +0,0 @@
|
||||
import { lookupProtobufType, ProtoSource } from './lookupProtobufType';
|
||||
|
||||
export function encodeProtobuf(
|
||||
source: ProtoSource,
|
||||
type: string,
|
||||
data: Record<string, any>,
|
||||
) {
|
||||
const message = lookupProtobufType(source, type);
|
||||
const verification = message.verify(data);
|
||||
|
||||
if (verification !== null) throw new Error(verification);
|
||||
|
||||
return message.encode(message.create(data)).finish();
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
import { encodeProtobuf } from './encodeProtobuf';
|
||||
import { ProtoSource } from './lookupProtobufType';
|
||||
|
||||
export async function encodeProtobufToBase64(
|
||||
source: ProtoSource,
|
||||
type: string,
|
||||
data: any,
|
||||
) {
|
||||
const array = encodeProtobuf(source, type, data);
|
||||
return Buffer.from(array).toString('base64');
|
||||
}
|
||||
@@ -1,4 +0,0 @@
|
||||
export * from './decodeProtobuf';
|
||||
export * from './encodeProtobuf';
|
||||
export * from './encodeProtobufToBase64';
|
||||
export * from './lookupProtobufType';
|
||||
@@ -1,12 +0,0 @@
|
||||
import protobuf from 'protobufjs';
|
||||
import average_definitions from '../../protos/average_definitions.proto';
|
||||
import reviews from '../../protos/reviews.proto';
|
||||
import tank_definitions from '../../protos/tank_definitions.proto';
|
||||
|
||||
export type ProtoSource = keyof typeof protos;
|
||||
|
||||
const protos = { reviews, average_definitions, tank_definitions };
|
||||
|
||||
export function lookupProtobufType(source: ProtoSource, type: string) {
|
||||
return protobuf.parse(protos[source]).root.lookupType(type);
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
export * from './generated';
|
||||
File renamed without changes.
File renamed without changes.
+45
-29
@@ -41,9 +41,9 @@ message TankDefinition {
|
||||
}
|
||||
|
||||
enum TankPriceType {
|
||||
TYPE_UNSPECIFIED = 0;
|
||||
TYPE_CREDITS = 1;
|
||||
TYPE_GOLD = 2;
|
||||
TANK_PRICE_TYPE_UNSPECIFIED = 0;
|
||||
TANK_PRICE_TYPE_CREDITS = 1;
|
||||
TANK_PRICE_TYPE_GOLD = 2;
|
||||
}
|
||||
|
||||
message TankPrice {
|
||||
@@ -103,16 +103,32 @@ message GunDefinitionRegular {
|
||||
GunDefinitionRegularProperties regular = 2;
|
||||
}
|
||||
|
||||
message GunDefinitionRegularProperties {
|
||||
float reload = 1;
|
||||
}
|
||||
|
||||
message GunDefinitionAutoLoader {
|
||||
GunDefinitionBase gun = 1;
|
||||
GunDefinitionAutoLoaderProperties auto_loader = 2;
|
||||
}
|
||||
|
||||
message GunDefinitionAutoLoaderProperties {
|
||||
float clip_reload = 1;
|
||||
float intra_clip = 2;
|
||||
float shell_count = 3;
|
||||
}
|
||||
|
||||
message GunDefinitionAutoReloader {
|
||||
GunDefinitionBase gun = 1;
|
||||
GunDefinitionAutoReloaderProperties auto_reloader = 2;
|
||||
}
|
||||
|
||||
message GunDefinitionAutoReloaderProperties {
|
||||
repeated float shell_reloads = 1;
|
||||
float intra_clip = 2;
|
||||
float shell_count = 3;
|
||||
}
|
||||
|
||||
message GunDefinitionBase {
|
||||
uint32 id = 1;
|
||||
float rotation_speed = 2;
|
||||
@@ -146,11 +162,11 @@ message ShellDefinition {
|
||||
}
|
||||
|
||||
enum ShellType {
|
||||
SHELL_UNSPECIFIED = 0;
|
||||
SHELL_AP = 1;
|
||||
SHELL_APCR = 2;
|
||||
SHELL_HEAT = 3;
|
||||
SHELL_HE = 4;
|
||||
SHELL_TYPE_UNSPECIFIED = 0;
|
||||
SHELL_TYPE_AP = 1;
|
||||
SHELL_TYPE_APCR = 2;
|
||||
SHELL_TYPE_HEAT = 3;
|
||||
SHELL_TYPE_HE = 4;
|
||||
}
|
||||
|
||||
message ShellPenetration {
|
||||
@@ -170,20 +186,20 @@ message UnlockCost {
|
||||
}
|
||||
|
||||
enum ModuleType {
|
||||
MODULE_UNSPECIFIED = 0;
|
||||
MODULE_VEHICLE = 1;
|
||||
MODULE_ENGINE = 2;
|
||||
MODULE_TRACKS = 3;
|
||||
MODULE_TURRET = 4;
|
||||
MODULE_GUN = 5;
|
||||
MODULE_TYPE_UNSPECIFIED = 0;
|
||||
MODULE_TYPE_VEHICLE = 1;
|
||||
MODULE_TYPE_ENGINE = 2;
|
||||
MODULE_TYPE_TRACKS = 3;
|
||||
MODULE_TYPE_TURRET = 4;
|
||||
MODULE_TYPE_GUN = 5;
|
||||
}
|
||||
|
||||
enum TankClass {
|
||||
CLASS_UNSPECIFIED = 0;
|
||||
CLASS_LIGHT = 1;
|
||||
CLASS_MEDIUM = 2;
|
||||
CLASS_HEAVY = 3;
|
||||
CLASS_TANK_DESTROYER = 4;
|
||||
TANK_CLASS_UNSPECIFIED = 0;
|
||||
TANK_CLASS_LIGHT = 1;
|
||||
TANK_CLASS_MEDIUM = 2;
|
||||
TANK_CLASS_HEAVY = 3;
|
||||
TANK_CLASS_TANK_DESTROYER = 4;
|
||||
}
|
||||
|
||||
enum Tier {
|
||||
@@ -201,10 +217,10 @@ enum Tier {
|
||||
}
|
||||
|
||||
enum TankType {
|
||||
TYPE_UNSPECIFIED = 0;
|
||||
TYPE_RESEARCHABLE = 1;
|
||||
TYPE_PREMIUM = 2;
|
||||
TYPE_COLLECTOR = 3;
|
||||
TANK_TYPE_UNSPECIFIED = 0;
|
||||
TANK_TYPE_RESEARCHABLE = 1;
|
||||
TANK_TYPE_PREMIUM = 2;
|
||||
TANK_TYPE_COLLECTOR = 3;
|
||||
}
|
||||
|
||||
message Crew {
|
||||
@@ -214,10 +230,10 @@ message Crew {
|
||||
}
|
||||
|
||||
enum CrewType {
|
||||
CREW_UNSPECIFIED = 0;
|
||||
CREW_COMMANDER = 1;
|
||||
CREW_RADIOMAN = 2;
|
||||
CREW_GUNNER = 3;
|
||||
CREW_DRIVER = 4;
|
||||
CREW_LOADER = 5;
|
||||
CREW_TYPE_UNSPECIFIED = 0;
|
||||
CREW_TYPE_COMMANDER = 1;
|
||||
CREW_TYPE_RADIOMAN = 2;
|
||||
CREW_TYPE_GUNNER = 3;
|
||||
CREW_TYPE_DRIVER = 4;
|
||||
CREW_TYPE_LOADER = 5;
|
||||
}
|
||||
@@ -1,16 +1,41 @@
|
||||
import { $ } from 'bun';
|
||||
import { readdir } from 'fs/promises';
|
||||
import { exec as execSync } from 'child_process';
|
||||
import { existsSync } from 'fs';
|
||||
import { cp, mkdir, readdir, rm, writeFile } from 'fs/promises';
|
||||
import { promisify } from 'util';
|
||||
|
||||
const ROOT = 'packages/core/protos';
|
||||
const ROOT = 'packages/core/src/protos';
|
||||
|
||||
const exec = promisify(execSync);
|
||||
|
||||
let executableFileExtension: string;
|
||||
|
||||
if (existsSync('node_modules/.bin/protoc-gen-ts.exe')) {
|
||||
executableFileExtension = '.exe';
|
||||
} else {
|
||||
executableFileExtension = '';
|
||||
}
|
||||
|
||||
const files = await readdir(`${ROOT}/raw`);
|
||||
const args = [
|
||||
'--plugin="./node_modules/.bin/protoc-gen-ts"',
|
||||
'--js_out="import_style=commonjs,binary:${OUT_DIR}"',
|
||||
`--ts_out="${ROOT}/generated"`,
|
||||
`--plugin="protoc-gen-ts=./node_modules/.bin/protoc-gen-ts${executableFileExtension}"`,
|
||||
'--ts_opt=esModuleInterop=true',
|
||||
`--js_out="import_style=commonjs,binary:./${ROOT}/generated"`,
|
||||
`--ts_out="./${ROOT}/generated"`,
|
||||
...files.map((file) => `${ROOT}/raw/${file}`),
|
||||
];
|
||||
|
||||
console.log(`protoc ${args.join(' ')}`);
|
||||
await rm(`${ROOT}/generated`, { recursive: true, force: true });
|
||||
await mkdir(`${ROOT}/generated`, { recursive: true });
|
||||
await exec(`protoc ${args.join(' ')}`);
|
||||
await cp(`${ROOT}/generated/${ROOT}/raw`, `${ROOT}/generated`, {
|
||||
recursive: true,
|
||||
});
|
||||
await rm(`${ROOT}/generated/packages`, { recursive: true, force: true });
|
||||
|
||||
console.log(await $`protoc ${args.join(' ')}`.text());
|
||||
await writeFile(
|
||||
`${ROOT}/generated/index.ts`,
|
||||
files
|
||||
.map((file) => file.replace('.proto', ''))
|
||||
.map((file) => `export * from './${file}_pb';`)
|
||||
.join('\n'),
|
||||
);
|
||||
Reference in new issue
Block a user