fix: read dvpl files

This commit is contained in:
TrèsAbhi committed 2025-11-26 13:25:46 -06:00
1 parent a0bccc7973
commit 9cb1d0cb3f
5 files changed
+54 -49

No files matched your search

+33 -32
View File
@@ -1,32 +1,33 @@
export * from './canSplash'; export * from "./canSplash";
export * from './clans'; export * from "./clans";
export * from './classes'; export * from "./classes";
export * from './constants'; export * from "./constants";
export * from './equipmentPrice'; export * from "./equipmentPrice";
export * from './fetchBlitz'; export * from "./fetchBlitz";
export * from './fetchGlossary'; export * from "./fetchGlossary";
export * from './generateStats'; export * from "./generateStats";
export * from './getAccountAchievements'; export * from "./getAccountAchievements";
export * from './getAccountInfo'; export * from "./getAccountInfo";
export * from './getClanAccountInfo'; export * from "./getClanAccountInfo";
export * from './getClanInfo'; export * from "./getClanInfo";
export * from './getLeagueFromScore'; export * from "./getLeagueFromScore";
export * from './getRatingInfo'; export * from "./getRatingInfo";
export * from './getRatingLeague'; export * from "./getRatingLeague";
export * from './getRatingNeighbors'; export * from "./getRatingNeighbors";
export * from './getTankStats'; export * from "./getTankStats";
export * from './idToRegion'; export * from "./idToRegion";
export * from './isOnGoingRatingSeason'; export * from "./isOnGoingRatingSeason";
export * from './isValidBlitzId'; export * from "./isValidBlitzId";
export * from './nations'; export * from "./nations";
export * from './normalizeExtra'; export * from "./normalizeExtra";
export * from './normalizeIds'; export * from "./normalizeIds";
export * from './permanentSkills'; export * from "./permanentSkills";
export * from './rating'; export * from "./rating";
export * from './regions'; export * from "./readDVPL";
export * from './regionSubdomainToRegion'; export * from "./regions";
export * from './regionToRegionSubdomain'; export * from "./regionSubdomainToRegion";
export * from './searchClansAcrossRegions'; export * from "./regionToRegionSubdomain";
export * from './searchCurrentRatingPlayers'; export * from "./searchClansAcrossRegions";
export * from './searchPlayersAcrossRegions'; export * from "./searchCurrentRatingPlayers";
export * from './toUniqueId'; export * from "./searchPlayersAcrossRegions";
export * from "./toUniqueId";
@@ -1,5 +1,5 @@
import { crc32 } from 'crc'; import { crc32 } from "crc";
import { decompressBlock } from 'lz4js'; import { decompressBlock } from "lz4js";
/** /**
* Thanks Maddoxkkm! Modified heavily to be modern. * Thanks Maddoxkkm! Modified heavily to be modern.
@@ -9,10 +9,10 @@ export function readDVPL(buffer: Buffer) {
const footerBuffer = buffer.subarray(buffer.length - 20, buffer.length); const footerBuffer = buffer.subarray(buffer.length - 20, buffer.length);
if ( if (
footerBuffer.toString('utf8', 16, 20) !== 'DVPL' || footerBuffer.toString("utf8", 16, 20) !== "DVPL" ||
footerBuffer.length !== 20 footerBuffer.length !== 20
) { ) {
throw new SyntaxError('Invalid DVPL footer'); throw new SyntaxError("Invalid DVPL footer");
} }
const footerData = { const footerData = {
@@ -24,15 +24,15 @@ export function readDVPL(buffer: Buffer) {
const targetBlock = buffer.subarray(0, buffer.length - 20); const targetBlock = buffer.subarray(0, buffer.length - 20);
if (targetBlock.length !== footerData.cSize) { if (targetBlock.length !== footerData.cSize) {
throw new RangeError('DVPL size mismatch'); throw new RangeError("DVPL size mismatch");
} }
if (crc32(targetBlock) !== footerData.crc32) { if (crc32(targetBlock) !== footerData.crc32) {
throw new TypeError('DVPL CRC32 mismatch'); throw new TypeError("DVPL CRC32 mismatch");
} }
if (footerData.type === 0) { if (footerData.type === 0) {
if (!(footerData.oSize === footerData.cSize && footerData.type === 0)) { if (!(footerData.oSize === footerData.cSize && footerData.type === 0)) {
throw new RangeError('DVPL type and size mismatch'); throw new RangeError("DVPL type and size mismatch");
} }
return targetBlock; return targetBlock;
@@ -44,17 +44,17 @@ export function readDVPL(buffer: Buffer) {
destination, destination,
0, 0,
source.length, source.length,
0, 0
); );
if (decompressedSize !== footerData.oSize) { if (decompressedSize !== footerData.oSize) {
throw new RangeError( throw new RangeError(
`Decompressed DVPL size mismatch (${decompressedSize} vs ${footerData.oSize})`, `Decompressed DVPL size mismatch (${decompressedSize} vs ${footerData.oSize})`
); );
} }
return Buffer.from(destination); return Buffer.from(destination);
} else { } else {
throw new SyntaxError('Unknown DVPL format'); throw new SyntaxError("Unknown DVPL format");
} }
} }
+6 -2
View File
@@ -1,6 +1,7 @@
import { XMLParser } from "fast-xml-parser"; import { XMLParser } from "fast-xml-parser";
import SteamUser, { EConnectionProtocol } from "steam-user"; import SteamUser, { EConnectionProtocol } from "steam-user";
import { parse } from "yaml"; import { parse } from "yaml";
import { readDVPL } from "../blitz";
interface SteamManifestFile { interface SteamManifestFile {
chunks: { chunks: {
@@ -91,7 +92,7 @@ export class SteamVFS {
assert(requested: string) { assert(requested: string) {
const path = this.has(requested); const path = this.has(requested);
if (!path) throw new Error(`File not found: ${path}`); if (!path) throw new Error(`File not found: ${requested}`);
return path; return path;
} }
@@ -120,8 +121,11 @@ export class SteamVFS {
const downloaded: { type: "complete"; file: Buffer } = const downloaded: { type: "complete"; file: Buffer } =
// @ts-expect-error // @ts-expect-error
await this.steam.downloadFile(this.app, this.depot, fileManifest); await this.steam.downloadFile(this.app, this.depot, fileManifest);
let buffer = downloaded.file;
return new Uint8Array(downloaded.file); if (path.endsWith(".dvpl")) buffer = readDVPL(downloaded.file);
return new Uint8Array(buffer);
} }
async text(path: string) { async text(path: string) {
@@ -3,9 +3,9 @@ import { assertSecret, SteamVFS } from "@blitzkit/core";
const APP = 444200; const APP = 444200;
const DEPOT = 444202; const DEPOT = 444202;
export const vfs = new SteamVFS( export const vfs = await new SteamVFS(
assertSecret(import.meta.env.STEAM_USERNAME), assertSecret(import.meta.env.STEAM_USERNAME),
assertSecret(import.meta.env.STEAM_PASSWORD), assertSecret(import.meta.env.STEAM_PASSWORD),
APP, APP,
DEPOT DEPOT
); ).init();
+1 -1
View File
@@ -1,4 +1,4 @@
{ {
"extends": "../../tsconfig.json", "extends": "../../tsconfig.json",
"include": ["src/**/*"] "include": ["src/**/*", "../core/src/blitz/readDVPL.ts"]
} }