unreal.js
Version:
A pak reader for games like VALORANT & Fortnite written in Node.JS
140 lines (139 loc) • 7.24 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.FIoContainerHeader = exports.EIoContainerHeaderVersion = exports.FIoContainerHeaderLocalizedPackage = exports.FIoContainerHeaderPackageRedirect = exports.FFilePackageStoreEntry = void 0;
const Game_1 = require("../versions/Game");
const AsyncLoading2_1 = require("../asyncloading2/AsyncLoading2");
const FNameMap_1 = require("../asyncloading2/FNameMap");
const Utils_1 = require("../../util/Utils");
const collection_1 = __importDefault(require("@discordjs/collection"));
class FFilePackageStoreEntry {
// public shaderMapHashes: Buffer[]
constructor(Ar) {
this.exportCount = 0;
this.exportBundleCount = 0;
if (Ar.game >= Game_1.Game.GAME_UE5_BASE) {
this.exportCount = Ar.readInt32();
this.exportBundleCount = Ar.readInt32();
this.importedPackages = FFilePackageStoreEntry.readCArrayView(Ar);
Ar.pos += 8; // shaderMapHashes
}
}
static readCArrayView(Ar /*, init: (Ar: FArchive) => T*/) {
const initialPos = Ar.pos;
const arrayNum = Ar.readInt32();
const offsetToDataFromThis = Ar.readInt32();
if (arrayNum <= 0)
return [];
const continuePos = Ar.pos;
Ar.pos = initialPos + offsetToDataFromThis;
const result = new Array(arrayNum);
for (let i = 0; i < arrayNum; ++i) {
result[i] = Ar.readUInt64(); // init(Ar)
}
Ar.pos = continuePos;
return result;
}
}
exports.FFilePackageStoreEntry = FFilePackageStoreEntry;
class FIoContainerHeaderPackageRedirect {
constructor(Ar) {
this.sourcePackageId = Ar.readUInt64();
this.targetPackageId = Ar.readUInt64();
this.sourcePackageName = Ar.game >= Game_1.Game.GAME_UE5_BASE ? new AsyncLoading2_1.FMappedName(Ar) : null;
}
}
exports.FIoContainerHeaderPackageRedirect = FIoContainerHeaderPackageRedirect;
class FIoContainerHeaderLocalizedPackage {
constructor(Ar) {
this.sourcePackageId = Ar.readUInt64();
this.sourcePackageName = new AsyncLoading2_1.FMappedName(Ar);
}
}
exports.FIoContainerHeaderLocalizedPackage = FIoContainerHeaderLocalizedPackage;
var EIoContainerHeaderVersion;
(function (EIoContainerHeaderVersion) {
EIoContainerHeaderVersion[EIoContainerHeaderVersion["BeforeVersionWasAdded"] = -1] = "BeforeVersionWasAdded";
EIoContainerHeaderVersion[EIoContainerHeaderVersion["Initial"] = 0] = "Initial";
EIoContainerHeaderVersion[EIoContainerHeaderVersion["LocalizedPackages"] = 1] = "LocalizedPackages";
EIoContainerHeaderVersion[EIoContainerHeaderVersion["OptionalSegmentPackages"] = 2] = "OptionalSegmentPackages";
EIoContainerHeaderVersion[EIoContainerHeaderVersion["Latest"] = 1] = "Latest";
})(EIoContainerHeaderVersion = exports.EIoContainerHeaderVersion || (exports.EIoContainerHeaderVersion = {}));
class FIoContainerHeader {
constructor(Ar) {
this.optionalSegmentPackageIds = null;
this.optionalSegmentStoreEntries = null;
this.redirectsNameMap = new FNameMap_1.FNameMap();
this.localizedPackages = null;
this.culturePackageMap = null;
let version = Ar.game >= Game_1.Game.GAME_UE5_BASE ? EIoContainerHeaderVersion.Initial : EIoContainerHeaderVersion.BeforeVersionWasAdded;
if (version == EIoContainerHeaderVersion.Initial) {
const signature = Ar.readInt32();
if (signature !== FIoContainerHeader.SIGNATURE)
throw new TypeError(`Invalid container header signature (${FIoContainerHeader.SIGNATURE}): ${signature}`);
version = Ar.readInt32();
}
this.containerId = Ar.readUInt64();
if (version == EIoContainerHeaderVersion.BeforeVersionWasAdded) {
const packageCount = Ar.readUInt32();
const names = Ar.read(Ar.readInt32());
const nameHashes = Ar.read(Ar.readInt32());
if (Utils_1.Utils.bufferIsNotEmpty(names)) {
this.redirectsNameMap.load(names, nameHashes, AsyncLoading2_1.FMappedName_EType.Container);
}
}
const pkgLen = Ar.readInt32();
this.packageIds = new Array(pkgLen);
for (let i = 0; i < pkgLen; ++i)
this.packageIds[i] = Ar.readUInt64();
const storeEntriesNum = Ar.readInt32();
const storeEntriesEnd = Ar.pos + storeEntriesNum;
const strsLen = this.packageIds.length;
this.storeEntries = new Array(strsLen);
for (let i = 0; i < strsLen; ++i) {
this.storeEntries[i] = new FFilePackageStoreEntry(Ar);
}
Ar.pos = storeEntriesEnd;
if (version >= EIoContainerHeaderVersion.OptionalSegmentPackages) {
this.optionalSegmentPackageIds = new Array(Ar.readInt32());
for (let i = 0; i < this.optionalSegmentPackageIds.length; ++i)
this.optionalSegmentPackageIds[i] = Ar.readUInt64();
const optionalSegmentStoreEntriesNum = Ar.readInt32();
const optionalSegmentStoreEntriesEnd = Ar.pos + optionalSegmentStoreEntriesNum;
this.optionalSegmentStoreEntries = new Array(this.optionalSegmentPackageIds.length);
for (let i = 0; i < this.optionalSegmentStoreEntries.length; ++i)
this.optionalSegmentStoreEntries[i] = new FFilePackageStoreEntry(Ar);
Ar.pos = optionalSegmentStoreEntriesEnd;
}
if (version >= EIoContainerHeaderVersion.Initial)
this.redirectsNameMap.load(Ar, AsyncLoading2_1.FMappedName_EType.Container);
if (version >= EIoContainerHeaderVersion.LocalizedPackages) {
const locPkgLen = Ar.readInt32();
this.localizedPackages = new Array(locPkgLen);
for (let i = 0; i < locPkgLen; ++i)
this.localizedPackages[i] = new FIoContainerHeaderLocalizedPackage(Ar);
}
else {
this.culturePackageMap = new collection_1.default();
const culPkgLen = Ar.readInt32();
for (let i = 0; i < culPkgLen; ++i) {
const key = Ar.readString();
const valLen = Ar.readInt32();
const value = new Array(valLen);
for (let x = 0; x < valLen; ++x) {
value[x] = new FIoContainerHeaderPackageRedirect(Ar);
}
this.culturePackageMap.set(key, value);
}
}
const pkgRedLen = Ar.readInt32();
this.packageRedirects = new Array(pkgRedLen);
for (let i = 0; i < pkgRedLen; ++i)
this.packageRedirects[i] = new FIoContainerHeaderPackageRedirect(Ar);
}
}
exports.FIoContainerHeader = FIoContainerHeader;
FIoContainerHeader.SIGNATURE = 0x496f436e;
// https://github.com/FabianFG/JFortniteParse/commit/f4290eca74a73012891f5266f2c846dc2562acb9#diff-4f3637b59bb48138b87dfd324a31bf9bbec05425698578bc5836756c38b66742