♻️ Move parsing and extracting into modules
This commit is contained in:
parent
2dae5f6c58
commit
62a877617b
4 changed files with 57 additions and 25 deletions
|
@ -1,29 +1,14 @@
|
|||
import { TextDecoder } from 'util';
|
||||
import extractFile from './ssn/extractFile';
|
||||
import getPatchmanifest from './ssn/getPatchmanifest';
|
||||
import getSolidpkg from './ssn/getSolidpkg';
|
||||
import readSsnFile from './ssn/readSsnFile';
|
||||
|
||||
const Decoder = new TextDecoder('utf-8');
|
||||
|
||||
(async () => {
|
||||
//----- PATCHMANIFEST -----
|
||||
//.patchmanifest files contain a single XML file called "manifest.xml"
|
||||
const patchmanifestBuffer = await getPatchmanifest('assets_swtor_de_de');
|
||||
console.log(patchmanifestBuffer.byteLength, patchmanifestBuffer);
|
||||
|
||||
const patchmanifestFiles = readSsnFile(patchmanifestBuffer);
|
||||
console.log(patchmanifestFiles);
|
||||
|
||||
const patchmanifestFile = extractFile(patchmanifestFiles[0], [new DataView(patchmanifestBuffer)]);
|
||||
const patchmanifestXml = Decoder.decode(patchmanifestFile);
|
||||
const patchmanifestXml = await getPatchmanifest('assets_swtor_de_de');
|
||||
console.log(patchmanifestXml);
|
||||
|
||||
//----- SOLIDPKG -----
|
||||
//.solidpkg files contain a single Bencode file called "metafile.solid"
|
||||
const solidpkgBuffer = await getSolidpkg('assets_swtor_de_de', -1, 0);
|
||||
console.log(solidpkgBuffer.byteLength, solidpkgBuffer);
|
||||
|
||||
const solidPkgFiles = readSsnFile(solidpkgBuffer);
|
||||
console.log(solidPkgFiles);
|
||||
const solidFile = await getSolidpkg('assets_swtor_de_de', -1, 0);
|
||||
console.log(solidFile);
|
||||
})();
|
||||
|
|
|
@ -41,7 +41,7 @@ class ByteReader {
|
|||
/** Extracts the given file from the given DataView array and returns it as an ArrayBuffer.
|
||||
* Will throw an error when end of final DataView is reached.
|
||||
*/
|
||||
export default function extractFile(file: ISsnFileEntry, dvArray: DataView[]): ArrayBuffer {
|
||||
export default async function extractFile(file: ISsnFileEntry, dvArray: DataView[]): Promise<ArrayBuffer> {
|
||||
//use ByteReader for reading a uint8 and seeking forward across DataView boundaries
|
||||
const byteReader = new ByteReader(dvArray, file.diskNumberStart, file.offset);
|
||||
|
||||
|
@ -61,6 +61,10 @@ export default function extractFile(file: ISsnFileEntry, dvArray: DataView[]): A
|
|||
}
|
||||
|
||||
//uncompress file
|
||||
const uncompressedBuffer = zlib.inflateRawSync(dvFinal);
|
||||
const uncompressedBuffer: Buffer = await new Promise((resolve) => {
|
||||
zlib.inflateRaw(dvFinal, (error, result) => {
|
||||
resolve(result);
|
||||
});
|
||||
}) as Buffer;
|
||||
return uncompressedBuffer.buffer as ArrayBuffer;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,36 @@
|
|||
import { TextDecoder } from 'util';
|
||||
import getUrlContents from '../getUrlContents';
|
||||
import { Product } from '../interfaces/ISettings';
|
||||
import verifyProductName from '../verifyProductName';
|
||||
import extractFile from './extractFile';
|
||||
import readSsnFile from './readSsnFile';
|
||||
|
||||
export default function getPatchmanifest(product: Product): Promise<ArrayBuffer> {
|
||||
const Decoder = new TextDecoder('utf-8');
|
||||
|
||||
export default async function getPatchmanifest(product: Product): Promise<string> {
|
||||
//Verify function arguments
|
||||
if (!verifyProductName(product)) {
|
||||
throw new Error(`"${product}" is not a valid product.`);
|
||||
}
|
||||
|
||||
return getUrlContents({ host: 'manifest.swtor.com', path: `/patch/${product}.patchmanifest` });
|
||||
//Download .patchmanifest file
|
||||
const ssnFile = await getUrlContents({ host: 'manifest.swtor.com', path: `/patch/${product}.patchmanifest` });
|
||||
|
||||
//Parse .patchmanifest file
|
||||
const fileEntries = readSsnFile(ssnFile);
|
||||
|
||||
if (fileEntries.length !== 1) {
|
||||
throw new Error(`Expected .patchmanifest to contain 1 file but it had "${fileEntries.length}" files.`);
|
||||
}
|
||||
|
||||
const firstFile = fileEntries[0];
|
||||
if (firstFile.name !== 'manifest.xml') {
|
||||
throw new Error(`Expected .patchmanifest to contain a file called manifest.xml but it is called "${firstFile.name}".`);
|
||||
}
|
||||
|
||||
//Extract manifest.xml file
|
||||
const patchmanifestFile = await extractFile(firstFile, [new DataView(ssnFile)]);
|
||||
const patchmanifestXml = Decoder.decode(patchmanifestFile);
|
||||
|
||||
return patchmanifestXml;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,14 @@
|
|||
import getUrlContents from '../getUrlContents';
|
||||
import { Product } from '../interfaces/ISettings';
|
||||
import verifyProductName from '../verifyProductName';
|
||||
import extractFile from './extractFile';
|
||||
import readSsnFile from './readSsnFile';
|
||||
|
||||
export default function getSolidpkg(product: Product, from: number, to: number): Promise<ArrayBuffer> {
|
||||
export default async function getSolidpkg(product: Product, from: number, to: number): Promise<ArrayBuffer> {
|
||||
//Verify function arguments
|
||||
if (!verifyProductName(product)) {
|
||||
throw new Error(`"${product}" is not a valid product.`);
|
||||
}
|
||||
|
||||
if (typeof from !== 'number' || (from | 0) !== from || from < -1) {
|
||||
throw new Error(`from must be an integer greater than or equal to -1 but it is "${from}"`);
|
||||
}
|
||||
|
@ -18,5 +19,23 @@ export default function getSolidpkg(product: Product, from: number, to: number):
|
|||
throw new Error(`from must be less than to but "${from}" is not less than "${to}".`);
|
||||
}
|
||||
|
||||
return getUrlContents({ host: 'cdn-patch.swtor.com', path: `/patch/${product}/${product}_${from}to${to}.solidpkg` });
|
||||
//Download .solidpkg file
|
||||
const ssnFile = await getUrlContents({ host: 'cdn-patch.swtor.com', path: `/patch/${product}/${product}_${from}to${to}.solidpkg` });
|
||||
|
||||
//Parse .solidpkg file
|
||||
const fileEntries = readSsnFile(ssnFile);
|
||||
|
||||
if (fileEntries.length !== 1) {
|
||||
throw new Error(`Expected .solidpkg to contain 1 file but it had "${fileEntries.length}" files.`);
|
||||
}
|
||||
|
||||
const firstFile = fileEntries[0];
|
||||
if (firstFile.name !== 'metafile.solid') {
|
||||
throw new Error(`Expected .solidpkg to contain a file called metafile.solid but it is called "${firstFile.name}".`);
|
||||
}
|
||||
|
||||
//Extract metafile.solid file
|
||||
const solidFile = await extractFile(firstFile, [new DataView(ssnFile)]);
|
||||
|
||||
return solidFile;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue