@runejs/filestore
Version:
Tools for managing the RuneJS filestore.
89 lines (88 loc) • 3.44 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.Archive = void 0;
const common_1 = require("@runejs/common");
const file_data_1 = require("./file-data");
const data_1 = require("./data");
class Archive extends file_data_1.FileData {
/**
* A map of files housed within this Archive.
*/
files;
/**
* The type of file, either an `archive` or a plain `file`.
*/
type = 'archive';
decoded = false;
constructor(idOrFileData, index, filestoreChannels) {
super(typeof idOrFileData === 'number'
? idOrFileData
: idOrFileData.fileId, index, filestoreChannels);
if (typeof idOrFileData !== 'number') {
const fileData = idOrFileData;
const { content, nameHash, crc, whirlpool, version, compression } = fileData;
this.content = content;
this.nameHash = nameHash;
this.crc = crc;
this.whirlpool = whirlpool;
this.version = version;
this.compression = compression;
}
this.files = new Map();
}
/**
* Fetches a file from this Archive by ID.
* @param fileId The ID of the file to find.
*/
getFile(fileId) {
return this.files.get(fileId) || null;
}
/**
* Decodes the packed Archive files from the filestore on disk.
*/
decodeArchiveFiles() {
if (this.decoded) {
return;
}
const archiveEntry = (0, data_1.readIndexedDataChunk)(this.fileId, this.index.indexId, this.filestoreChannels);
const { compression, version, buffer } = (0, data_1.decompress)(archiveEntry.dataFile);
const archiveSize = this.files.size;
this.content = buffer;
this.version = version;
this.content = buffer;
this.compression = compression;
this.files.clear();
buffer.readerIndex = buffer.length - 1;
const chunkCount = buffer.get('BYTE', 'UNSIGNED');
const chunkSizes = new Array(chunkCount).fill(new Array(archiveSize));
const sizes = new Array(archiveSize).fill(0);
buffer.readerIndex = buffer.length - 1 - chunkCount * archiveSize * 4;
for (let chunk = 0; chunk < chunkCount; chunk++) {
let chunkSize = 0;
for (let id = 0; id < archiveSize; id++) {
const delta = buffer.get('INT');
chunkSize += delta;
chunkSizes[chunk][id] = chunkSize;
sizes[id] += chunkSize;
}
}
for (let id = 0; id < archiveSize; id++) {
const fileData = new file_data_1.FileData(id, this.index, this.filestoreChannels);
fileData.content = new common_1.ByteBuffer(sizes[id]);
this.files.set(id, fileData);
}
buffer.readerIndex = 0;
for (let chunk = 0; chunk < chunkCount; chunk++) {
for (let id = 0; id < archiveSize; id++) {
const chunkSize = chunkSizes[chunk][id];
this.files
.get(id)
.content.putBytes(buffer.getSlice(buffer.readerIndex, chunkSize));
buffer.copy(this.files.get(id).content, 0, buffer.readerIndex, buffer.readerIndex + chunkSize);
buffer.readerIndex = buffer.readerIndex + chunkSize;
}
}
this.decoded = true;
}
}
exports.Archive = Archive;