mirror of
https://github.com/blitzkit/blitzkit.git
synced 2026-10-23 19:49:50 +02:00
feat: uhh
This commit is contained in:
1 parent
fdf77a43cb
commit
4c2f6bea25
7 files changed
+136
-56
No files matched your search
Vendored
+4
@@ -3,6 +3,7 @@
|
|||||||
"AABBOX",
|
"AABBOX",
|
||||||
"Abhi",
|
"Abhi",
|
||||||
"accountinfo",
|
"accountinfo",
|
||||||
|
"alphatest",
|
||||||
"bepaint",
|
"bepaint",
|
||||||
"BINORMAL",
|
"BINORMAL",
|
||||||
"blitzstars",
|
"blitzstars",
|
||||||
@@ -12,6 +13,7 @@
|
|||||||
"CUBETEXCOORD",
|
"CUBETEXCOORD",
|
||||||
"customperiod",
|
"customperiod",
|
||||||
"deburr",
|
"deburr",
|
||||||
|
"decalmask",
|
||||||
"diacriticless",
|
"diacriticless",
|
||||||
"dvpl",
|
"dvpl",
|
||||||
"DVPLCRC",
|
"DVPLCRC",
|
||||||
@@ -28,6 +30,7 @@
|
|||||||
"Leaderboard",
|
"Leaderboard",
|
||||||
"leaderboards",
|
"leaderboards",
|
||||||
"MURICA",
|
"MURICA",
|
||||||
|
"normalmap",
|
||||||
"Oopsy",
|
"Oopsy",
|
||||||
"outdir",
|
"outdir",
|
||||||
"outfile",
|
"outfile",
|
||||||
@@ -45,6 +48,7 @@
|
|||||||
"searchtanks",
|
"searchtanks",
|
||||||
"SKLLD",
|
"SKLLD",
|
||||||
"Smri",
|
"Smri",
|
||||||
|
"Specularity",
|
||||||
"startcase",
|
"startcase",
|
||||||
"statsfull",
|
"statsfull",
|
||||||
"steamapps",
|
"steamapps",
|
||||||
|
|||||||
+65
-1
@@ -1,8 +1,10 @@
|
|||||||
import { config } from 'dotenv';
|
import { config } from 'dotenv';
|
||||||
import { readdir } from 'fs/promises';
|
import { existsSync } from 'fs';
|
||||||
|
import { mkdir, readdir, rm } from 'fs/promises';
|
||||||
import { argv } from 'process';
|
import { argv } from 'process';
|
||||||
import { TankType } from '../src/components/Tanks';
|
import { TankType } from '../src/components/Tanks';
|
||||||
import { NATION_IDS } from '../src/constants/nations';
|
import { NATION_IDS } from '../src/constants/nations';
|
||||||
|
import { SCPGStream } from '../src/core/blitz/SCPGStream';
|
||||||
import { readBase64DVPL } from '../src/core/blitz/readBase64DVPL';
|
import { readBase64DVPL } from '../src/core/blitz/readBase64DVPL';
|
||||||
import { readXMLDVPL } from '../src/core/blitz/readXMLDVPL';
|
import { readXMLDVPL } from '../src/core/blitz/readXMLDVPL';
|
||||||
import { readYAMLDVPL } from '../src/core/blitz/readYAMLDVPL';
|
import { readYAMLDVPL } from '../src/core/blitz/readYAMLDVPL';
|
||||||
@@ -43,6 +45,7 @@ interface TankParameters {
|
|||||||
resourcesPath: {
|
resourcesPath: {
|
||||||
smallIconPath: string;
|
smallIconPath: string;
|
||||||
bigIconPath: string;
|
bigIconPath: string;
|
||||||
|
blitzModelPath: string;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -62,6 +65,7 @@ const DOI = {
|
|||||||
smallIcons: 'Gfx/UI/BattleScreenHUD/SmallTankIcons',
|
smallIcons: 'Gfx/UI/BattleScreenHUD/SmallTankIcons',
|
||||||
bigIcons: 'Gfx/UI/BigTankIcons',
|
bigIcons: 'Gfx/UI/BigTankIcons',
|
||||||
flags: 'Gfx/Lobby/flags',
|
flags: 'Gfx/Lobby/flags',
|
||||||
|
'3d': '3d',
|
||||||
};
|
};
|
||||||
|
|
||||||
const allTargets = argv.includes('--all-targets');
|
const allTargets = argv.includes('--all-targets');
|
||||||
@@ -269,3 +273,63 @@ if (allTargets || targets?.includes('circleFlags')) {
|
|||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (allTargets || targets?.includes('tankModels')) {
|
||||||
|
console.log('Building tank models...');
|
||||||
|
|
||||||
|
if (existsSync('dist/assets/models')) {
|
||||||
|
await rm('dist/assets/models', { recursive: true });
|
||||||
|
}
|
||||||
|
await mkdir('dist/assets/models', { recursive: true });
|
||||||
|
|
||||||
|
const changes: FileChange[] = [];
|
||||||
|
const nations = await readdir(`${DATA}/${DOI.vehicleDefinitions}`).then(
|
||||||
|
(nations) => nations.filter((nation) => nation !== 'common'),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
[nations[0]].map(async (nation) => {
|
||||||
|
const tanks = await readXMLDVPL<VehicleDefinitionList>(
|
||||||
|
`${DATA}/${DOI.vehicleDefinitions}/${nation}/list.xml.dvpl`,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const tankIndex in tanks) {
|
||||||
|
const tank = tanks[tankIndex];
|
||||||
|
const nationVehicleId = tank.id;
|
||||||
|
const id = (nationVehicleId << 8) + (NATION_IDS[nation] << 4) + 1;
|
||||||
|
|
||||||
|
// if (id !== 817) continue;
|
||||||
|
console.log(`Building model ${id} @ ${nation}/${tankIndex}`);
|
||||||
|
|
||||||
|
const parameters = await readYAMLDVPL<TankParameters>(
|
||||||
|
`${DATA}/${DOI.tankParameters}/${nation}/${tankIndex}.yaml.dvpl`,
|
||||||
|
);
|
||||||
|
const sc2Path = parameters.resourcesPath.blitzModelPath;
|
||||||
|
// const scgPath = parameters.resourcesPath.blitzModelPath.replace(
|
||||||
|
// /\.sc2$/,
|
||||||
|
// '.scg',
|
||||||
|
// );
|
||||||
|
const sc2Stream = await SCPGStream.fromDVPLFile(
|
||||||
|
`${DATA}/${DOI['3d']}/${sc2Path}.dvpl`,
|
||||||
|
);
|
||||||
|
// const scgStream = await SCPGStream.fromDVPLFile(
|
||||||
|
// `${DATA}/${DOI['3d']}/${scgPath}.dvpl`,
|
||||||
|
// );
|
||||||
|
const sc2Data = sc2Stream.consumeSC2();
|
||||||
|
// const scgData = scgStream.consumeSCG();
|
||||||
|
|
||||||
|
// writeFile(`dist/assets/models/${id}.json`, JSON.stringify(scgData));
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
// console.log('Committing tank icons...');
|
||||||
|
// await commitMultipleFiles(
|
||||||
|
// 'tresabhi',
|
||||||
|
// 'blitzkrieg-assets',
|
||||||
|
// 'main',
|
||||||
|
// 'tank icons',
|
||||||
|
// changes,
|
||||||
|
// true,
|
||||||
|
// );
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { writeFileSync } from 'fs';
|
|
||||||
import { readFile } from 'fs/promises';
|
|
||||||
import { range } from 'lodash';
|
import { range } from 'lodash';
|
||||||
|
import { readDVPL } from './readDVPL';
|
||||||
|
import { readDVPLFile } from './readDVPLFile';
|
||||||
|
|
||||||
enum KAType {
|
enum KAType {
|
||||||
NONE,
|
NONE,
|
||||||
@@ -55,6 +55,31 @@ enum VertexType {
|
|||||||
CUBETEXCOORD3,
|
CUBETEXCOORD3,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface SCPGBuffer {
|
||||||
|
type: 'Buffer';
|
||||||
|
data: number[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PolygonGroupRaw {
|
||||||
|
'##name': 'PolygonGroup';
|
||||||
|
'#id': Buffer;
|
||||||
|
cubeTextureCoordCount: number;
|
||||||
|
indexCount: number;
|
||||||
|
indexFormat: 0 | 1;
|
||||||
|
indices: Buffer;
|
||||||
|
packing: 0 | 1;
|
||||||
|
primitiveCount: number;
|
||||||
|
rhi_primitiveType: 1 | 2 | 10;
|
||||||
|
textureCoordCount: number;
|
||||||
|
vertexCount: number;
|
||||||
|
vertexFormat: number;
|
||||||
|
vertices: Buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface PolygonGroup extends Omit<PolygonGroupRaw, 'indices'> {
|
||||||
|
indices: number[];
|
||||||
|
}
|
||||||
|
|
||||||
const VECTOR_SIZES = [
|
const VECTOR_SIZES = [
|
||||||
[
|
[
|
||||||
// vector 1; basically array of 1 number
|
// vector 1; basically array of 1 number
|
||||||
@@ -90,27 +115,7 @@ const VECTOR_SIZES = [
|
|||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
interface PolygonGroupRaw {
|
export class SCPGStream {
|
||||||
'##name': 'PolygonGroup';
|
|
||||||
'#id': Buffer;
|
|
||||||
cubeTextureCoordCount: number;
|
|
||||||
indexCount: number;
|
|
||||||
indexFormat: 0 | 1;
|
|
||||||
indices: Buffer;
|
|
||||||
packing: 0 | 1;
|
|
||||||
primitiveCount: number;
|
|
||||||
rhi_primitiveType: 1 | 2 | 10;
|
|
||||||
textureCoordCount: number;
|
|
||||||
vertexCount: number;
|
|
||||||
vertexFormat: number;
|
|
||||||
vertices: Buffer;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface PolygonGroup extends Omit<PolygonGroupRaw, 'indices'> {
|
|
||||||
indices: number[];
|
|
||||||
}
|
|
||||||
|
|
||||||
class SCPGStream {
|
|
||||||
public index = 0;
|
public index = 0;
|
||||||
|
|
||||||
constructor(public buffer: Buffer) {}
|
constructor(public buffer: Buffer) {}
|
||||||
@@ -165,7 +170,10 @@ class SCPGStream {
|
|||||||
return this.consume(2).readUInt16LE();
|
return this.consume(2).readUInt16LE();
|
||||||
}
|
}
|
||||||
consumeUInt32() {
|
consumeUInt32() {
|
||||||
return this.consume(4).readUInt32LE();
|
const buffer = this.consume(4);
|
||||||
|
const value = buffer.readUInt32LE();
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
consumeUInt64() {
|
consumeUInt64() {
|
||||||
return this.consume(8).readBigUInt64LE();
|
return this.consume(8).readBigUInt64LE();
|
||||||
@@ -210,6 +218,7 @@ class SCPGStream {
|
|||||||
const verticesStream = new SCPGStream(polygonGroupRaw.vertices);
|
const verticesStream = new SCPGStream(polygonGroupRaw.vertices);
|
||||||
const vertexFormat = polygonGroupRaw.vertexFormat
|
const vertexFormat = polygonGroupRaw.vertexFormat
|
||||||
.toString(2)
|
.toString(2)
|
||||||
|
.padStart(8 * 8, '0')
|
||||||
.split('')
|
.split('')
|
||||||
.map(parseInt)
|
.map(parseInt)
|
||||||
.map((bit, index) => (bit ? index : null))
|
.map((bit, index) => (bit ? index : null))
|
||||||
@@ -247,36 +256,31 @@ class SCPGStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
consumeSC2Header() {
|
consumeSC2Header() {
|
||||||
return {
|
const header = {
|
||||||
name: this.consumeAscii(4),
|
name: this.consumeAscii(4),
|
||||||
version: this.consumeUInt32(),
|
version: this.consumeUInt32(),
|
||||||
nodeCount: this.consumeUInt32(),
|
nodeCount: this.consumeUInt32(),
|
||||||
};
|
};
|
||||||
|
const version = this.consumeKA();
|
||||||
|
const descriptor = this.consumeSC2Descriptor(header.version);
|
||||||
|
|
||||||
|
return { header, version, descriptor };
|
||||||
}
|
}
|
||||||
consumeSC2Descriptor() {
|
consumeSC2Descriptor(version: number) {
|
||||||
const size = this.consumeUInt32();
|
const size = this.consumeUInt32();
|
||||||
const fileType = this.consumeUInt32();
|
const fileType = this.consumeUInt32();
|
||||||
|
|
||||||
this.skip(8); // other felids that we don't care about for some reason
|
// other felids that we don't care about for some reason lol
|
||||||
|
this.skip(size - 4);
|
||||||
|
|
||||||
return { size, fileType };
|
return { size, fileType };
|
||||||
}
|
}
|
||||||
consumeSC2() {
|
consumeSC2() {
|
||||||
const header = this.consumeSC2Header();
|
console.log(this.consumeSC2Header());
|
||||||
const versionTags = this.consumeKA();
|
|
||||||
const descriptor = this.consumeSC2Descriptor();
|
|
||||||
const data = this.consumeKA();
|
|
||||||
|
|
||||||
writeFileSync(
|
console.log(this.read(32).toString('ascii'));
|
||||||
'test.json',
|
|
||||||
JSON.stringify(
|
|
||||||
{ header, versionTags, descriptor, data },
|
|
||||||
(key, value) => (typeof value === 'bigint' ? value.toString() : value),
|
|
||||||
2,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// console.log(data);
|
return this.consumeKA();
|
||||||
}
|
}
|
||||||
|
|
||||||
consumeKAHeader() {
|
consumeKAHeader() {
|
||||||
@@ -319,11 +323,9 @@ class SCPGStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
case KAType.KEYED_ARCHIVE: {
|
case KAType.KEYED_ARCHIVE: {
|
||||||
this.skip(4); // the length
|
this.skip(4); // UInt32 length of the nested archive in bytes
|
||||||
|
|
||||||
const value = this.consumeKA<Type>(stringTable);
|
return this.consumeKA<Type>(stringTable);
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case KAType.UINT64:
|
case KAType.UINT64:
|
||||||
@@ -372,6 +374,8 @@ class SCPGStream {
|
|||||||
const header = this.consumeKAHeader();
|
const header = this.consumeKAHeader();
|
||||||
const pairs: Record<string, any> = {};
|
const pairs: Record<string, any> = {};
|
||||||
|
|
||||||
|
console.log(header);
|
||||||
|
|
||||||
if (header.version === 1) {
|
if (header.version === 1) {
|
||||||
for (let index = 0; index < header.count; index++) {
|
for (let index = 0; index < header.count; index++) {
|
||||||
const { name, value } = this.consumeKAV1Pair();
|
const { name, value } = this.consumeKAV1Pair();
|
||||||
@@ -421,8 +425,12 @@ class SCPGStream {
|
|||||||
|
|
||||||
return pairs as Type;
|
return pairs as Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static fromDVPL(buffer: Buffer) {
|
||||||
|
return new SCPGStream(readDVPL(buffer));
|
||||||
|
}
|
||||||
|
|
||||||
|
static async fromDVPLFile(file: string) {
|
||||||
|
return new SCPGStream(await readDVPLFile(file));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const stream = new SCPGStream(await readFile('test.sc2'));
|
|
||||||
|
|
||||||
stream.consumeSC2();
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { readDVPL } from './readDVPL';
|
import { readDVPLFile } from './readDVPLFile';
|
||||||
|
|
||||||
export async function readBase64DVPL(file: string) {
|
export async function readBase64DVPL(file: string) {
|
||||||
const buffer = await readDVPL(file);
|
const buffer = await readDVPLFile(file);
|
||||||
return buffer.toString('base64');
|
return buffer.toString('base64');
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,4 @@
|
|||||||
import { crc32 } from 'crc';
|
import { crc32 } from 'crc';
|
||||||
import { readFile } from 'fs/promises';
|
|
||||||
import { decodeBlock } from 'lz4';
|
import { decodeBlock } from 'lz4';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -7,8 +6,7 @@ import { decodeBlock } from 'lz4';
|
|||||||
*
|
*
|
||||||
* https://github.com/Maddoxkkm/dvpl_converter/
|
* https://github.com/Maddoxkkm/dvpl_converter/
|
||||||
*/
|
*/
|
||||||
export async function readDVPL(file: string) {
|
export function readDVPL(buffer: Buffer) {
|
||||||
const buffer = await readFile(file);
|
|
||||||
const footerBuffer = buffer.subarray(buffer.length - 20, buffer.length);
|
const footerBuffer = buffer.subarray(buffer.length - 20, buffer.length);
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
import { readFile } from 'fs/promises';
|
||||||
|
import { readDVPL } from './readDVPL';
|
||||||
|
|
||||||
|
export async function readDVPLFile(file: string) {
|
||||||
|
return readDVPL(await readFile(file));
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { readDVPL } from './readDVPL';
|
import { readDVPLFile } from './readDVPLFile';
|
||||||
|
|
||||||
export async function readStringDVPL(file: string) {
|
export async function readStringDVPL(file: string) {
|
||||||
const buffer = await readDVPL(file);
|
const buffer = await readDVPLFile(file);
|
||||||
return buffer.toString();
|
return buffer.toString();
|
||||||
}
|
}
|
||||||
Reference in new issue
Block a user