UNPKG

unpak.js

Version:

Modern TypeScript library for reading Unreal Engine pak files and assets, inspired by CUE4Parse

164 lines 6.47 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FValueHandle = exports.FPartialMapHandle = exports.ELoadOrder = exports.FStore = exports.END_MAGIC = exports.BEGIN_MAGIC = exports.OLD_BEGIN_MAGIC = void 0; const AssetDataTagMap_1 = require("./AssetDataTagMap"); const NameTypes_1 = require("../../objects/uobject/NameTypes"); const Exceptions_1 = require("../../../exceptions/Exceptions"); exports.OLD_BEGIN_MAGIC = 0x12345678; exports.BEGIN_MAGIC = 0x12345679; exports.END_MAGIC = 0x87654321; /** Stores a fixed set of values and all the key-values maps used for lookup */ class FStore { Ar; constructor(Ar) { this.Ar = Ar; this.nameMap = this.Ar.names; // init const initialMagic = Ar.readUInt32(); const order = this.getLoadOrder(initialMagic); if (!order) throw new Exceptions_1.ParserException("Bad init magic", Ar); const nums = new Array(11); for (let i = 0; i < 11; ++i) { nums[i] = Ar.readInt32(); } if (order === ELoadOrder.TextFirst) { const textDataBytes = Ar.readUInt32(); const len = nums[4]; this.texts = new Array(len); for (let i = 0; i < len; ++i) { this.texts[i] = Ar.readString(); } } const len1 = nums[0]; this.numberlessNames = new Array(len1); for (let i = 0; i < len1; ++i) { this.numberlessNames[i] = new NameTypes_1.FNameEntryId(Ar); } const len2 = nums[1]; this.names = new Array(len2); for (let i = 0; i < len2; ++i) { this.names[i] = Ar.readFName(); } const len3 = nums[2]; this.numberlessExportPaths = new Array(len3); for (let i = 0; i < len3; ++i) { this.numberlessExportPaths[i] = new AssetDataTagMap_1.FNumberlessExportPath(Ar, this.nameMap); } const len4 = nums[3]; this.exportPaths = new Array(len4); for (let i = 0; i < len4; ++i) { this.exportPaths[i] = new AssetDataTagMap_1.FAssetRegistryExportPath(Ar); } if (order === ELoadOrder.Member) { const _len = nums[4]; this.texts = new Array(_len); for (let i = 0; i < _len; ++i) { this.texts[i] = Ar.readString(); } } const len5 = nums[5]; this.ansiStringOffsets = new Array(len5); for (let i = 0; i < len5; ++i) { this.ansiStringOffsets[i] = Ar.readUInt32(); } const len6 = nums[6]; this.wideStringOffsets = new Array(len6); for (let i = 0; i < len6; ++i) { this.wideStringOffsets[i] = Ar.readUInt32(); } this.ansiStrings = Ar.read(nums[7]); this.wideStrings = Ar.wrappedAr.read(nums[8] * 2); const len7 = nums[9]; this.numberlessPairs = new Array(len7); for (let i = 0; i < len7; ++i) { this.numberlessPairs[i] = new AssetDataTagMap_1.FNumberlessPair(Ar); } const len8 = nums[10]; this.pairs = new Array(len8); for (let i = 0; i < len8; ++i) { this.pairs[i] = new AssetDataTagMap_1.FNumberedPair(Ar); } if (Ar.readUInt32() !== exports.END_MAGIC) throw new Error("Bytes did not match 'END_MAGIC' at end"); } // Pairs for all unsorted maps that uses this store pairs; numberlessPairs; // Values for all maps in this store ansiStringOffsets; ansiStrings; wideStringOffsets; wideStrings; numberlessNames; names; numberlessExportPaths; exportPaths; texts = []; // FText objects serialized in NSLOCTEXT() strings nameMap; getLoadOrder(initialMagic) { return initialMagic === exports.OLD_BEGIN_MAGIC ? ELoadOrder.Member : initialMagic === exports.BEGIN_MAGIC ? ELoadOrder.TextFirst : null; } getAnsiString(idx) { const offset = this.ansiStringOffsets[idx]; let length = 0; while (this.ansiStrings[offset + length] !== 0) ++length; return this.ansiStrings.subarray(offset, offset + length).toString("utf-8"); } getWideString(idx) { const offset = this.wideStringOffsets[idx]; var length = 0; while (this.wideStrings[offset + length] !== 0 && this.wideStrings[offset + length + 1] !== 0) length += 2; return this.wideStrings.subarray(offset, offset + length).toString("utf16le"); } } exports.FStore = FStore; var ELoadOrder; (function (ELoadOrder) { ELoadOrder["Member"] = "Member"; ELoadOrder["TextFirst"] = "TextFirst"; })(ELoadOrder || (exports.ELoadOrder = ELoadOrder = {})); class FPartialMapHandle { int; bHasNumberlessKeys; num; pairBegin; constructor(int) { this.int = int; this.bHasNumberlessKeys = int >> 63 > 0; this.num = int >> 32; this.pairBegin = int; } makeFullHandle(store) { return new AssetDataTagMap_1.FMapHandle(this, store); } toInt() { return ((this.bHasNumberlessKeys ? 1 : 0) << 63) | (this.num << 32) | this.pairBegin; } } exports.FPartialMapHandle = FPartialMapHandle; class FValueHandle { store; id; constructor(store, id) { this.store = store; this.id = id; } asString() { const index = this.id.index; return this.id.type === AssetDataTagMap_1.EValueType.AnsiString ? this.store.getAnsiString(index) : this.id.type === AssetDataTagMap_1.EValueType.WideString ? this.store.getWideString(index) : this.id.type === AssetDataTagMap_1.EValueType.NumberlessName ? this.store.nameMap[this.store.numberlessNames[index].value] : this.id.type === AssetDataTagMap_1.EValueType.Name ? this.store.names[index].text : this.id.type === AssetDataTagMap_1.EValueType.NumberlessExportPath ? this.store.numberlessExportPaths[index].toString() : this.id.type === AssetDataTagMap_1.EValueType.ExportPath ? this.store.exportPaths[index].toString() : this.id.type === AssetDataTagMap_1.EValueType.LocalizedText ? this.store.texts[index].toString() : ""; } } exports.FValueHandle = FValueHandle; //# sourceMappingURL=AssetDataTagMapSerializationDetails.js.map