UNPKG

xcom2charpool

Version:

Library for reading, manipulating, and managing XCOM 2 character pool binary files, supporting both browser and Node.js environments.

92 lines (91 loc) 4 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Unpacker = void 0; const NoneProperty_1 = require("./Properties/NoneProperty"); const ArrayProperty_1 = require("./Properties/ArrayProperty"); const BoolProperty_1 = require("./Properties/BoolProperty"); const ByteProperty_1 = require("./Properties/ByteProperty"); const IntProperty_1 = require("./Properties/IntProperty"); const NameProperty_1 = require("./Properties/NameProperty"); const StrProperty_1 = require("./Properties/StrProperty"); const StructProperty_1 = require("./Properties/StructProperty"); const CharacterPoolDataElements_1 = require("./Arrays/CharacterPoolDataElements"); const ArrayOfStructs_1 = require("./Arrays/ArrayOfStructs"); class Unpacker { get position() { return this.reader.position; } get length() { return this.reader.length; } constructor(reader) { this.reader = reader; } readFile() { const magic = this.reader.uint32(); if (magic !== 0xffffffff) { throw new Error(`Incorrect file magic 0x${magic.toString(16).padStart(8, '0')}`); } const state = this.properties(); // Почему-то внизу файла присобачен еще один массив const arr = ArrayProperty_1.ArrayProperty.from(this.reader, CharacterPoolDataElements_1.CharacterPoolDataElements.name, this.reader.length - this.reader.position); const data = new CharacterPoolDataElements_1.CharacterPoolDataElements(arr, (reader) => new Unpacker(reader)); if (this.reader.position < this.reader.length) { throw new Error(`Reader is not in the end of file! ${this.reader.length - this.reader.position} bytes remains`); } return { state, data }; } properties() { const props = {}; while (this.reader.position < this.reader.length) { const prop = this.property(); if (!prop) return props; props[prop.name] = prop.property; } return props; } property() { const name = this.reader.string(); this.reader.padding(); if (name === NoneProperty_1.NoneProperty.PropertyName) return; const type = this.reader.string(); this.reader.padding(); const factory = this.constructor.types[type]; if (!factory) { throw new Error(`Unknown property type ${type} with name ${name}`); } const size = this.reader.uint32(); this.reader.padding(); const property = factory.from(this.reader, name, size, (reader) => new Unpacker(reader)); if (property instanceof ArrayProperty_1.ArrayProperty) { const factory = this.constructor.knownArrays[name]; if (factory) { return { name, property: factory.from(property, name, (reader) => new Unpacker(reader)) }; } else { console.warn(`[Unpacker] Array of unknown type ${name}`); } } return { name, property }; } } exports.Unpacker = Unpacker; Unpacker.types = { [ArrayProperty_1.ArrayProperty.name]: ArrayProperty_1.ArrayProperty, [BoolProperty_1.BoolProperty.name]: BoolProperty_1.BoolProperty, [ByteProperty_1.ByteProperty.name]: ByteProperty_1.ByteProperty, [IntProperty_1.IntProperty.name]: IntProperty_1.IntProperty, [NameProperty_1.NameProperty.name]: NameProperty_1.NameProperty, [StrProperty_1.StrProperty.name]: StrProperty_1.StrProperty, [StructProperty_1.StructProperty.name]: StructProperty_1.StructProperty, }; Unpacker.knownArrays = { CharacterPool: ArrayOfStructs_1.ArrayOfStructs, ExtraDatas: ArrayOfStructs_1.ArrayOfStructs, AppearanceStore: ArrayOfStructs_1.ArrayOfStructs, CharacterPoolLoadout: ArrayOfStructs_1.ArrayOfStructs, UniformSettings: ArrayOfStructs_1.ArrayOfStructs, CosmeticOptions: ArrayOfStructs_1.ArrayOfStructs, };