Files
blitzkit/packages/scripts/src/core/blitz/readDVPL.ts
T

60 lines
1.7 KiB
TypeScript
Raw Normal View History

2023-12-05 17:59:58 -06:00
import { crc32 } from 'crc';
2024-06-22 17:46:16 -05:00
import { decompressBlock } from 'lz4js';
2023-12-05 17:59:58 -06:00
/**
2024-06-22 17:46:16 -05:00
* Thanks Maddoxkkm! Modified heavily to be modern.
2023-12-05 17:59:58 -06:00
* https://github.com/Maddoxkkm/dvpl_converter/
*/
2023-12-09 15:56:25 -06:00
export function readDVPL(buffer: Buffer) {
2023-12-05 18:05:14 -06:00
const footerBuffer = buffer.subarray(buffer.length - 20, buffer.length);
2023-12-05 17:59:58 -06:00
if (
footerBuffer.toString('utf8', 16, 20) !== 'DVPL' ||
footerBuffer.length !== 20
) {
2023-12-05 18:05:14 -06:00
throw new SyntaxError('Invalid DVPL footer');
2023-12-05 17:59:58 -06:00
}
const footerData = {
oSize: footerBuffer.readUInt32LE(0),
cSize: footerBuffer.readUInt32LE(4),
crc32: footerBuffer.readUInt32LE(8),
type: footerBuffer.readUInt32LE(12),
};
2023-12-05 18:05:14 -06:00
const targetBlock = buffer.subarray(0, buffer.length - 20);
2023-12-05 17:59:58 -06:00
2023-12-05 18:05:14 -06:00
if (targetBlock.length !== footerData.cSize) {
throw new RangeError('DVPL size mismatch');
}
if (crc32(targetBlock) !== footerData.crc32) {
throw new TypeError('DVPL CRC32 mismatch');
}
2024-06-22 17:46:16 -05:00
2023-12-05 17:59:58 -06:00
if (footerData.type === 0) {
if (!(footerData.oSize === footerData.cSize && footerData.type === 0)) {
2023-12-05 18:05:14 -06:00
throw new RangeError('DVPL type and size mismatch');
2023-12-05 17:59:58 -06:00
}
return targetBlock;
} else if (footerData.type === 1 || footerData.type === 2) {
2024-06-22 17:46:16 -05:00
const source = new Uint8Array(targetBlock);
const destination = new Uint8Array(footerData.oSize);
const decompressedSize = decompressBlock(
source,
destination,
0,
source.length,
0,
);
2025-04-05 02:07:35 +00:00
2024-06-22 17:46:16 -05:00
if (decompressedSize !== footerData.oSize) {
throw new RangeError(
`Decompressed DVPL size mismatch (${decompressedSize} vs ${footerData.oSize})`,
);
2023-12-05 17:59:58 -06:00
}
2025-04-05 02:07:35 +00:00
2024-06-22 17:46:16 -05:00
return Buffer.from(destination);
2023-12-05 17:59:58 -06:00
} else {
2023-12-05 18:05:14 -06:00
throw new SyntaxError('Unknown DVPL format');
2023-12-05 17:59:58 -06:00
}
}