forked from phenom/healer-man
42 lines
2.0 KiB
JavaScript
42 lines
2.0 KiB
JavaScript
/** Reconstruct the exact scalar/string semantics of positional archive rows. */
|
|
export function archiveRowsToDbc(records, fieldTypes) {
|
|
if (!Array.isArray(fieldTypes) || fieldTypes.length !== 234) throw new Error("Archived Spell requires all 234 column types");
|
|
const strings = [Buffer.from([0])];
|
|
let stringSize = 1;
|
|
const stringOffsets = new Map([["", 0]]);
|
|
const rows = records.map((record) => {
|
|
const row = Buffer.alloc(234 * 4);
|
|
for (let index = 0; index < 234; index += 1) {
|
|
const key = `f${index}`;
|
|
if (!Object.hasOwn(record, key)) throw new Error(`Archived spell ${record.f0} is missing ${key}`);
|
|
const value = record[key];
|
|
const localized = (index >= 136 && index <= 151) || (index >= 153 && index <= 168)
|
|
|| (index >= 170 && index <= 185) || (index >= 187 && index <= 202);
|
|
const text = typeof value === "string" ? value : localized && typeof record[`${key}s`] === "string" ? record[`${key}s`] : null;
|
|
if (text !== null) {
|
|
if (!stringOffsets.has(text)) {
|
|
const bytes = Buffer.from(`${text}\0`, "utf8");
|
|
stringOffsets.set(text, stringSize);
|
|
strings.push(bytes);
|
|
stringSize += bytes.length;
|
|
}
|
|
row.writeUInt32LE(stringOffsets.get(text), index * 4);
|
|
} else if (fieldTypes[index] === "float") {
|
|
if (!Number.isFinite(value)) throw new Error(`Archived spell ${record.f0} has invalid ${key}`);
|
|
row.writeFloatLE(value, index * 4);
|
|
} else {
|
|
if (!Number.isInteger(value) || value < -2147483648 || value > 4294967295) throw new Error(`Archived spell ${record.f0} has invalid integer ${key}`);
|
|
row.writeUInt32LE(value >>> 0, index * 4);
|
|
}
|
|
}
|
|
return row;
|
|
});
|
|
const header = Buffer.alloc(20);
|
|
header.write("WDBC", 0);
|
|
header.writeUInt32LE(rows.length, 4);
|
|
header.writeUInt32LE(234, 8);
|
|
header.writeUInt32LE(234 * 4, 12);
|
|
header.writeUInt32LE(stringSize, 16);
|
|
return Buffer.concat([header, ...rows, ...strings]);
|
|
}
|