UNPKG

unreal.js

Version:

A pak reader for games like VALORANT & Fortnite written in Node.JS

89 lines (88 loc) 4.05 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FPakEntry = void 0; const FPakCompressedBlock_1 = require("./FPakCompressedBlock"); const PakVersion_1 = require("../enums/PakVersion"); const Game_1 = require("../../versions/Game"); /** * FPakEntry */ class FPakEntry { /** * Creates an instance using values * @param {?FArchive} Ar UE4 Reader to use * @param {?FPakInfo} pakInfo Pak info * @param {?boolean} inIndex Whether in index * @constructor * @public */ constructor(Ar, pakInfo, inIndex) { if (!Ar) return; this.name = inIndex ? Ar.readString() : ""; this.pos = Number(Ar.readInt64()); this.size = Number(Ar.readInt64()); this.uncompressedSize = Number(Ar.readInt64()); if (pakInfo.version >= PakVersion_1.EPakVersion.PakVersion_FNameBasedCompressionMethod) { const int = Ar.readInt32(); this.compressionMethod = pakInfo.compressionMethods[int] || (Ar.game === Game_1.Game.GAME_VALORANT ? "None" : "Unknown"); } else { this.compressionMethod = ["None", undefined, undefined, undefined, "Oodle"][Ar.readInt32()] || (Ar.game === Game_1.Game.GAME_VALORANT ? "None" : "Unknown"); } if (pakInfo.version < PakVersion_1.EPakVersion.PakVersion_NoTimestamps) Ar.pos += 8; Ar.pos += 20; // hash this.compressionBlocks = []; if (pakInfo.version >= PakVersion_1.EPakVersion.PakVersion_CompressionEncryption) { if (this.compressionMethod !== "None") { const len = Ar.readInt32(); this.compressionBlocks = new Array(len); for (let i = 0; i < len; ++i) { this.compressionBlocks[i] = new FPakCompressedBlock_1.FPakCompressedBlock(Ar); } } this.isEncrypted = Ar.readFlag(); //Looks like Valorant sets the encryption flag to false although inis are encrypted if (Ar.game === Game_1.Game.GAME_VALORANT && this.name.endsWith(".ini")) this.isEncrypted = true; //Note: This is not how it works in UE, default is Int8 but Fortnite uses Int32. // This project was originally intended to be used only with Fortnite, that's why it is twisted like that //compressionBlockSize = if (Ar.game == GAME_VALORANT) // Ar.readInt8().toInt() //else // Ar.readInt32() this.compressionBlockSize = Ar.readInt32(); } if (pakInfo.version >= PakVersion_1.EPakVersion.PakVersion_RelativeChunkOffsets) { for (const it of this.compressionBlocks) { it.compressedStart += this.pos; it.compressedEnd += this.pos; } } } /** * Calculates serialized size from specified values * @param {?number} version Version to use * @param {?number} compressionMethod Compression method to use * @param {?number} compressionBlocksCount Compression block count to use * @returns {number} Calculated size * @public * @static */ static getSerializedSize(version, compressionMethod = 0, compressionBlocksCount = 0) { let serializedSize = /*this.pos*/ 8 + /*this.size*/ 8 + /*this.uncompressedSize*/ 8 + /*this.hash*/ 20; serializedSize += 4; if (version >= PakVersion_1.EPakVersion.PakVersion_CompressionEncryption) { serializedSize += /*this.isEncrypted*/ 1 + /*this.compressionBlockSize*/ 4; if (compressionMethod !== 0) { serializedSize += /*FPakCompressedBlock*/ 8 * 2 * compressionBlocksCount + /*int32*/ 4; } } if (version < PakVersion_1.EPakVersion.PakVersion_NoTimestamps) { serializedSize += /*timestamp*/ 8; } return serializedSize; } } exports.FPakEntry = FPakEntry;