feat: read dvpl

This commit is contained in:
TrèsAbhi committed 2023-12-05 17:59:58 -06:00
1 parent ad0fc69596
commit 4bfe34ba53
5 files changed
+121 -24

No files matched your search

+3
View File
@@ -10,6 +10,8 @@
"customperiod",
"deburr",
"diacriticless",
"dvpl",
"DVPLCRC",
"Everytime",
"fullstats",
"fuzzysort",
@@ -38,6 +40,7 @@
"Smri",
"startcase",
"statsfull",
"steamapps",
"Stringifying",
"strvk",
"subnation",
+3
View File
@@ -65,12 +65,15 @@
"@types/express": "^4.17.18",
"@types/js-yaml": "^4.0.8",
"@types/lodash": "^4.14.199",
"@types/lz4": "^0.6.4",
"@types/markdown-escape": "^1.1.0",
"@types/node": "^20.6.5",
"@types/react": "^18.2.22",
"@vanilla-extract/next-plugin": "^2.3.1",
"compare-versions": "^6.1.0",
"crc": "^4.3.2",
"knip": "^3.4.0",
"lz4": "^0.6.5",
"prettier": "^3.0.3",
"prisma": "^5.4.1",
"typescript": "^5.2.2"
+25 -24
View File
@@ -1,13 +1,13 @@
import { Octokit } from '@octokit/rest';
import decompress from 'decompress';
import { config } from 'dotenv';
import { writeFileSync } from 'fs';
import { readFile, readdir, rm } from 'fs/promises';
import { readFile, readdir } from 'fs/promises';
import { load } from 'js-yaml';
import { argv, env } from 'process';
import { ElementCompact, xml2js } from 'xml-js';
import { parse } from 'yaml';
import { NATION_IDS } from '../src/constants/nations';
import { readDVPL } from '../src/core/blitz/readDVPL';
import {
TankDefinitions,
Tier,
@@ -16,39 +16,40 @@ import commitMultipleFiles, { FileChange } from './commitMultipleFiles';
config();
const DATA =
'C:/Program Files (x86)/Steam/steamapps/common/World of Tanks Blitz/Data';
const LANGUAGE = 'en';
const TEMP = 'temp/blitz';
const publish = argv.includes('--publish');
const apkFile = argv
.find((argument) => argument.startsWith('--file'))
?.split('=')[1];
const noRewrite = argv.includes('--no-rewrite');
const targets = argv
.find((argument) => argument.startsWith('--target'))
?.split('=')[1]
.split(',');
if (!apkFile) throw new Error('No file specified');
if (!targets) throw new Error('No target(s) specified');
const directoriesOfInterest = {
vehicleDefinitions: 'assets/Data/XML/item_defs/vehicles',
strings: 'assets/Data/Strings',
tankParameters: 'assets/Data/3d/Tanks/Parameters',
smallIcons: 'assets/Data/Gfx/UI/BattleScreenHUD/SmallTankIcons',
bigIcons: 'assets/Data/Gfx/UI/BigTankIcons',
flags: 'assets/Data/Gfx/Lobby/flags',
vehicleDefinitions: 'XML/item_defs/vehicles',
strings: 'Strings',
tankParameters: '3d/Tanks/Parameters',
smallIcons: 'Gfx/UI/BattleScreenHUD/SmallTankIcons',
bigIcons: 'Gfx/UI/BigTankIcons',
flags: 'Gfx/Lobby/flags',
};
const directoriesOfInterestArray = Object.values(directoriesOfInterest);
if (!noRewrite) {
await rm(TEMP, { recursive: true, force: true });
await decompress(apkFile, TEMP, {
filter: (file) =>
directoriesOfInterestArray.some((dir) => file.path.startsWith(dir)),
});
}
console.log(
(
await readDVPL(
`${DATA}/${directoriesOfInterest.strings}/${LANGUAGE}.yaml.dvpl`,
)
).toString(),
);
throw new Error('stop');
const strings = await readFile(
`${TEMP}/${directoriesOfInterest.strings}/${LANGUAGE}.yaml`,
`${DATA}/${directoriesOfInterest.strings}/${LANGUAGE}.yaml.dvpl`,
'utf-8',
).then((data) => load(data) as Record<string, string>);
const tankDefinitions: TankDefinitions = {};
const tankIds: number[] = [];
const images: Record<number, { big: string; small: string }> = {};
+49
View File
@@ -0,0 +1,49 @@
import { crc32 } from 'crc';
import { readFile } from 'fs/promises';
import { decodeBlock } from 'lz4';
/**
* Thanks Maddoxkkm! Modernized heavily.
*
* https://github.com/Maddoxkkm/dvpl_converter/
*/
export async function readDVPL(file: string) {
const buffer = await readFile(file);
const footerBuffer = buffer.slice(buffer.length - 20, buffer.length);
if (
footerBuffer.toString('utf8', 16, 20) !== 'DVPL' ||
footerBuffer.length !== 20
) {
throw 'InvalidDVPLFooter';
}
const footerData = {
oSize: footerBuffer.readUInt32LE(0),
cSize: footerBuffer.readUInt32LE(4),
crc32: footerBuffer.readUInt32LE(8),
type: footerBuffer.readUInt32LE(12),
};
const targetBlock = buffer.slice(0, buffer.length - 20);
if (targetBlock.length !== footerData.cSize) throw 'DVPLSizeMismatch';
if (crc32(targetBlock) !== footerData.crc32) throw 'DVPLCRC32Mismatch';
if (footerData.type === 0) {
if (!(footerData.oSize === footerData.cSize && footerData.type === 0)) {
throw 'DVPLTypeSizeMismatch';
}
return targetBlock;
} else if (footerData.type === 1 || footerData.type === 2) {
const deDVPLBlock = Buffer.alloc(footerData.oSize);
const DecompressedBlockSize = decodeBlock(targetBlock, deDVPLBlock);
if (DecompressedBlockSize !== footerData.oSize) {
throw 'DVPLDecodeSizeMismatch';
}
return deDVPLBlock;
} else {
throw new TypeError('Unknown DVPL format');
}
}
+41
View File
@@ -2027,6 +2027,13 @@
resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.202.tgz#f09dbd2fb082d507178b2f2a5c7e74bd72ff98f8"
integrity sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==
"@types/lz4@^0.6.4":
version "0.6.4"
resolved "https://registry.yarnpkg.com/@types/lz4/-/lz4-0.6.4.tgz#eba8c0bb9e6a997e78107092953c8cfa92733a46"
integrity sha512-vvxMIkowyHbY6zkCantyYwAK83N5E04bzFZSPJICG1SDpaL89L7lObs9DhLuhJhXHCQMkjzN3LYoAH6LjfwMFQ==
dependencies:
"@types/node" "*"
"@types/markdown-escape@^1.1.0":
version "1.1.3"
resolved "https://registry.yarnpkg.com/@types/markdown-escape/-/markdown-escape-1.1.3.tgz#b880ab7c1e23c76b1d663e5a5640107c493e0c3e"
@@ -2781,6 +2788,11 @@ core-util-is@~1.0.0:
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.3.tgz#a6042d3634c2b27e9328f837b965fac83808db85"
integrity sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==
crc@^4.3.2:
version "4.3.2"
resolved "https://registry.yarnpkg.com/crc/-/crc-4.3.2.tgz#49b7821cbf2cf61dfd079ed93863bbebd5469b9a"
integrity sha512-uGDHf4KLLh2zsHa8D8hIQ1H/HtFQhyHrc0uhHBcoKGol/Xnb+MPYfUMw7cvON6ze/GUESTudKayDcJC5HnJv1A==
cross-spawn@^7.0.0:
version "7.0.3"
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
@@ -2834,6 +2846,11 @@ csstype@^3.0.2, csstype@^3.0.7, csstype@^3.1.2:
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.2.tgz#1d4bf9d572f11c14031f0436e1c10bc1f571f50b"
integrity sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==
cuint@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/cuint/-/cuint-0.2.2.tgz#408086d409550c2631155619e9fa7bcadc3b991b"
integrity sha512-d4ZVpCW31eWwCMe1YT3ur7mUDnTXbgwyzaL320DrcRT45rfjYxkt5QWLrmOJ+/UEAI2+fQgKe/fCjR8l4TpRgw==
data-uri-to-buffer@^3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-3.0.1.tgz#594b8973938c5bc2c33046535785341abc4f3636"
@@ -3937,6 +3954,16 @@ lru-cache@^6.0.0:
dependencies:
yallist "^4.0.0"
lz4@^0.6.5:
version "0.6.5"
resolved "https://registry.yarnpkg.com/lz4/-/lz4-0.6.5.tgz#ae8b7522681b6ab155023e6c56bf73087090122b"
integrity sha512-KSZcJU49QZOlJSItaeIU3p8WoAvkTmD9fJqeahQXNu1iQ/kR0/mQLdbrK8JY9MY8f6AhJoMrihp1nu1xDbscSQ==
dependencies:
buffer "^5.2.1"
cuint "^0.2.2"
nan "^2.13.2"
xxhashjs "^0.2.2"
magic-bytes.js@^1.5.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/magic-bytes.js/-/magic-bytes.js-1.6.0.tgz#ee4354ac41a9b86f410e2690bc25dc4c264fb55d"
@@ -4168,6 +4195,11 @@ [email protected]:
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2"
integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==
nan@^2.13.2:
version "2.18.0"
resolved "https://registry.yarnpkg.com/nan/-/nan-2.18.0.tgz#26a6faae7ffbeb293a39660e88a76b82e30b7554"
integrity sha512-W7tfG7vMOGtD30sHoZSSc/JVYiyDPEyQVso/Zz+/uQd0B0L46gtC+pHha5FFMRpil6fm/AoEcRWyOVi4+E/f8w==
nanoid@^3.3.6, nanoid@^3.3.7:
version "3.3.7"
resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.7.tgz#d0c301a691bc8d54efa0a2226ccf3fe2fd656bd8"
@@ -4896,6 +4928,7 @@ streamsearch@^1.1.0:
integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg==
"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0:
name string-width-cjs
version "4.2.3"
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -4946,6 +4979,7 @@ stringify-entities@^4.0.0:
character-entities-legacy "^3.0.0"
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
name strip-ansi-cjs
version "6.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -5460,6 +5494,13 @@ xtend@^4.0.0:
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.2.tgz#bb72779f5fa465186b1f438f674fa347fdb5db54"
integrity sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==
xxhashjs@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/xxhashjs/-/xxhashjs-0.2.2.tgz#8a6251567621a1c46a5ae204da0249c7f8caa9d8"
integrity sha512-AkTuIuVTET12tpsVIQo+ZU6f/qDmKuRUcjaqR+OIvm+aCBsZ95i7UVY5WJ9TMsSaZ0DA2WxoZ4acu0sPH+OKAw==
dependencies:
cuint "^0.2.2"
yallist@^3.0.2:
version "3.1.1"
resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"