mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-21 18:57:03 +02:00
feat: more compression
This commit is contained in:
1 parent
afe041f969
commit
1575b803c0
11 files changed
+135
-59
No files matched your search
@@ -1,4 +1,5 @@
|
||||
import { asset } from './asset';
|
||||
import { fetchBkonLz4 } from './fetchBkonLz4';
|
||||
|
||||
export type TankFilterDefinitionCategory = 'clip';
|
||||
|
||||
@@ -33,9 +34,6 @@ export interface ConsumableDefinitions {
|
||||
[key: string]: ConsumableEntry;
|
||||
}
|
||||
|
||||
export const consumableDefinitions = fetch(
|
||||
asset('definitions/consumables.json'),
|
||||
{
|
||||
cache: 'no-cache',
|
||||
},
|
||||
).then(async (response) => response.json() as Promise<ConsumableDefinitions>);
|
||||
export const consumableDefinitions = fetchBkonLz4<ConsumableDefinitions>(
|
||||
asset('definitions/consumables.bkon.lz4'),
|
||||
);
|
||||
@@ -1,4 +1,5 @@
|
||||
import { asset } from './asset';
|
||||
import { fetchBkonLz4 } from './fetchBkonLz4';
|
||||
|
||||
type EquipmentOptions = [number, number];
|
||||
|
||||
@@ -21,6 +22,6 @@ export interface EquipmentDefinitions {
|
||||
};
|
||||
}
|
||||
|
||||
export const equipmentDefinitions = fetch(asset('definitions/equipment.json'), {
|
||||
cache: 'no-cache',
|
||||
}).then(async (response) => response.json() as Promise<EquipmentDefinitions>);
|
||||
export const equipmentDefinitions = fetchBkonLz4<EquipmentDefinitions>(
|
||||
asset('definitions/equipment.bkon.lz4'),
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
import { superDecompress } from './superDecompress';
|
||||
|
||||
export async function fetchBkonLz4<Type>(url: string) {
|
||||
return await fetch(url, {
|
||||
cache: 'no-cache',
|
||||
}).then(async (response) => {
|
||||
return superDecompress(Buffer.from(await response.arrayBuffer())) as Type;
|
||||
});
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Vector3Tuple } from 'three';
|
||||
import { asset } from './asset';
|
||||
import { fetchBkonLz4 } from './fetchBkonLz4';
|
||||
|
||||
export type ModelDefinitions = Record<number, ModelDefinition>;
|
||||
|
||||
@@ -53,6 +54,6 @@ export interface PitchLimits {
|
||||
transition?: number;
|
||||
}
|
||||
|
||||
export const modelDefinitions = fetch(asset('definitions/models.json'), {
|
||||
cache: 'no-cache',
|
||||
}).then(async (response) => response.json() as Promise<ModelDefinitions>);
|
||||
export const modelDefinitions = fetchBkonLz4<ModelDefinitions>(
|
||||
asset('definitions/models.bkon.lz4'),
|
||||
);
|
||||
@@ -1,5 +1,6 @@
|
||||
import { asset } from './asset';
|
||||
import { TankFilterDefinition } from './consumableDefinitions';
|
||||
import { fetchBkonLz4 } from './fetchBkonLz4';
|
||||
|
||||
export interface ProvisionEntry {
|
||||
id: number;
|
||||
@@ -13,9 +14,6 @@ export interface ProvisionDefinitions {
|
||||
[key: string]: ProvisionEntry;
|
||||
}
|
||||
|
||||
export const provisionDefinitions = fetch(
|
||||
asset('definitions/provisions.json'),
|
||||
{
|
||||
cache: 'no-cache',
|
||||
},
|
||||
).then(async (response) => response.json() as Promise<ProvisionDefinitions>);
|
||||
export const provisionDefinitions = fetchBkonLz4<ProvisionDefinitions>(
|
||||
asset('definitions/provisions.bkon.lz4'),
|
||||
);
|
||||
@@ -0,0 +1,8 @@
|
||||
import { encode } from 'lz4';
|
||||
import { BkonWriteStream } from '../streams/bkon';
|
||||
|
||||
export function superCompress(object: any) {
|
||||
const write = new BkonWriteStream().bkon(object);
|
||||
const compressed = encode(write.buffer);
|
||||
return compressed.toString('base64');
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
import { decode } from 'lz4';
|
||||
import { BkonReadStream } from '../streams/bkon';
|
||||
|
||||
export function superDecompress<Type>(buffer: Buffer) {
|
||||
const decompressed = decode(buffer);
|
||||
const read = new BkonReadStream(decompressed);
|
||||
return read.bkon() as Type;
|
||||
}
|
||||
@@ -2,6 +2,7 @@ import { deburr } from 'lodash';
|
||||
import { Vector2Tuple } from 'three';
|
||||
import { TankType, TreeType } from '../../components/Tanks';
|
||||
import { asset } from './asset';
|
||||
import { fetchBkonLz4 } from './fetchBkonLz4';
|
||||
|
||||
export type ShellType = 'ap' | 'ap_cr' | 'hc' | 'he';
|
||||
|
||||
@@ -117,9 +118,9 @@ export const GUN_TYPE_NAMES: Record<GunDefinition['type'], string> = {
|
||||
autoReloader: 'Auto reloader',
|
||||
};
|
||||
|
||||
export const tankDefinitions = fetch(asset('definitions/tanks.json'), {
|
||||
cache: 'no-cache',
|
||||
}).then(async (response) => response.json() as Promise<TankDefinitions>);
|
||||
export const tankDefinitions = fetchBkonLz4<TankDefinitions>(
|
||||
asset('definitions/tanks.bkon.lz4'),
|
||||
);
|
||||
|
||||
const entries = new Promise<TankDefinition[]>(async (resolve) => {
|
||||
resolve(Object.entries(await tankDefinitions).map(([, entry]) => entry));
|
||||
|
||||
+63
-21
@@ -20,20 +20,26 @@ enum ValueType {
|
||||
Object,
|
||||
}
|
||||
|
||||
type Value =
|
||||
enum FastStringFormat {
|
||||
Format8,
|
||||
Format16,
|
||||
Format32,
|
||||
}
|
||||
|
||||
export type BkonValue =
|
||||
| null
|
||||
| boolean
|
||||
| number
|
||||
| bigint
|
||||
| string
|
||||
| Value[]
|
||||
| { [key: string]: Value };
|
||||
| BkonValue[]
|
||||
| { [key: string]: BkonValue };
|
||||
|
||||
export class BkonReadStream extends ReadStream {
|
||||
bkon() {
|
||||
this.magic();
|
||||
const header = this.header();
|
||||
const body = this.body(header.stringTable);
|
||||
const body = this.body(header.fastStringFormat, header.stringTable);
|
||||
|
||||
return body;
|
||||
}
|
||||
@@ -47,12 +53,16 @@ export class BkonReadStream extends ReadStream {
|
||||
header() {
|
||||
return {
|
||||
version: this.uint16(),
|
||||
fastStringFormat: this.uint8() as FastStringFormat,
|
||||
stringTable: this.stringTable(),
|
||||
};
|
||||
}
|
||||
|
||||
body(stringTable: Record<number, string>) {
|
||||
return this.value(stringTable);
|
||||
body(
|
||||
fastStringFormat: FastStringFormat,
|
||||
stringTable: Record<number, string>,
|
||||
) {
|
||||
return this.value(fastStringFormat, stringTable);
|
||||
}
|
||||
|
||||
stringTable() {
|
||||
@@ -75,7 +85,10 @@ export class BkonReadStream extends ReadStream {
|
||||
return string;
|
||||
}
|
||||
|
||||
value(stringTable: Record<number, string>): Value {
|
||||
value(
|
||||
fastStringFormat: FastStringFormat,
|
||||
stringTable: Record<number, string>,
|
||||
): BkonValue {
|
||||
const type = this.uint8();
|
||||
|
||||
switch (type) {
|
||||
@@ -118,17 +131,34 @@ export class BkonReadStream extends ReadStream {
|
||||
case ValueType.String:
|
||||
return this.string();
|
||||
|
||||
case ValueType.FastString:
|
||||
return stringTable[this.uint16()];
|
||||
case ValueType.FastString: {
|
||||
switch (fastStringFormat) {
|
||||
case FastStringFormat.Format8:
|
||||
return stringTable[this.uint8()];
|
||||
|
||||
case FastStringFormat.Format16:
|
||||
return stringTable[this.uint16()];
|
||||
|
||||
case FastStringFormat.Format32:
|
||||
return stringTable[this.uint32()];
|
||||
}
|
||||
}
|
||||
|
||||
case ValueType.Array:
|
||||
return times(this.uint32(), () => this.value(stringTable));
|
||||
return times(this.uint32(), () =>
|
||||
this.value(fastStringFormat, stringTable),
|
||||
);
|
||||
|
||||
case ValueType.Object: {
|
||||
const count = this.uint32();
|
||||
const keys = times(count, () => this.value(stringTable) as string);
|
||||
const values = times(count, () => this.value(stringTable));
|
||||
const object: Record<string, Value> = {};
|
||||
const keys = times(
|
||||
count,
|
||||
() => this.value(fastStringFormat, stringTable) as string,
|
||||
);
|
||||
const values = times(count, () =>
|
||||
this.value(fastStringFormat, stringTable),
|
||||
);
|
||||
const object: Record<string, BkonValue> = {};
|
||||
|
||||
keys.forEach((string, index) => (object[string] = values[index]));
|
||||
|
||||
@@ -142,18 +172,20 @@ export class BkonReadStream extends ReadStream {
|
||||
}
|
||||
|
||||
export class BkonWriteStream extends WriteStream {
|
||||
bkon(object: Value) {
|
||||
bkon(object: BkonValue) {
|
||||
this.magic();
|
||||
const stringTable = this.header(object);
|
||||
this.body(object, stringTable);
|
||||
return this;
|
||||
}
|
||||
|
||||
body(object: Value, stringTable: Map<string, number>) {
|
||||
body(object: BkonValue, stringTable: Map<string, number>) {
|
||||
this.value(object, stringTable);
|
||||
return this;
|
||||
}
|
||||
|
||||
value(object: Value, stringTable: Map<string, number>) {
|
||||
if (object === null) {
|
||||
value(object: BkonValue, stringTable: Map<string, number>) {
|
||||
if (object === null || object === undefined) {
|
||||
this.uint8(ValueType.Null);
|
||||
} else if (typeof object === 'boolean') {
|
||||
this.uint8(ValueType.Boolean);
|
||||
@@ -226,17 +258,27 @@ export class BkonWriteStream extends WriteStream {
|
||||
}
|
||||
}
|
||||
|
||||
header(object: Value) {
|
||||
header(object: BkonValue) {
|
||||
this.uint16(1);
|
||||
return this.stringTable(object);
|
||||
}
|
||||
|
||||
stringTable(object: Value) {
|
||||
stringTable(object: BkonValue) {
|
||||
const stringTable = this.buildStringTable(
|
||||
this.collectStringCounts(object, new Map()),
|
||||
);
|
||||
|
||||
this.uint16(stringTable.size);
|
||||
if (stringTable.size <= 0xff) {
|
||||
this.uint8(FastStringFormat.Format8);
|
||||
this.uint8(stringTable.size);
|
||||
} else if (stringTable.size <= 0xffff) {
|
||||
this.uint8(FastStringFormat.Format16);
|
||||
this.uint16(stringTable.size);
|
||||
} else {
|
||||
this.uint8(FastStringFormat.Format32);
|
||||
this.uint32(stringTable.size);
|
||||
}
|
||||
|
||||
stringTable.forEach((_index, string) => this.string(string));
|
||||
|
||||
return stringTable;
|
||||
@@ -252,7 +294,7 @@ export class BkonWriteStream extends WriteStream {
|
||||
return stringTable;
|
||||
}
|
||||
|
||||
collectStringCounts(object: Value, stringCounts: Map<string, number>) {
|
||||
collectStringCounts(object: BkonValue, stringCounts: Map<string, number>) {
|
||||
if (typeof object === 'string') {
|
||||
if (stringCounts.has(object)) {
|
||||
stringCounts.set(object, stringCounts.get(object)! + 1);
|
||||
|
||||
Reference in new issue
Block a user