Last active
January 24, 2023 00:49
-
-
Save unisys12/30ecb24e447831d36e0dbc8a5624613a to your computer and use it in GitHub Desktop.
First attempt at decoding a PSARC Binary or .PAK file(from No Mans Sky) using Nodejs. This merely decodes the Header and TOC Table
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const fs = require("node:fs"); | |
const psarc_file = "./NMSARC.5A3E0C7D.pak"; | |
// const psarc_file = "./NMSARC.2E9559C7.pak"; | |
const hexToDecimal = (hex) => parseInt(hex, 16); | |
// Attempts to read a *pak file and decode it's header and | |
// return it as an object. Result in file below. | |
// | |
// Yes! This could be written better, but it's first draft. | |
// Ever wake up one morning and ask yourself, "Self! What's | |
// this all about? I wonder if we can do that?". | |
// | |
// This is just that. | |
// | |
const decode = fs.readFile(psarc_file, (err, buffer) => { | |
if (err) { | |
console.log(err); | |
} | |
// Grab only the header and toc_table of the psarc archive | |
let header = buffer.subarray(0, 62); | |
/** | |
* Converts the section of buffer to decimal. | |
* Removes any NULL bytes, then uses parseInt | |
* to convert to a decimal. Followed by comcat | |
* to conbine the result into a string | |
* | |
* @param start int | |
* @param end int | |
* @returns string | |
*/ | |
const toDecString = (start, end) => { | |
let result = []; | |
header.subarray(start, end).forEach((x) => { | |
if (x != 00) { | |
result.push(parseInt(x)); | |
} | |
}); | |
const string = "".concat(...result); | |
return hexToDecimal(string); | |
}; | |
/** | |
* Converts the section of buffer to decimal without | |
* destroying the orignal value. | |
* | |
* @param start int | |
* @param end int | |
* @returns int | |
*/ | |
const fromBinarytoDecString = (start, end) => { | |
let result = []; | |
const head_section = header.subarray(start, end); | |
head_section.forEach((x) => result.push("0" + x)); | |
const binary = "".concat(...result); | |
return hexToDecimal(binary); | |
}; | |
const header_data = { | |
magic: header.subarray(0, 4).toString(), // parse to string (type of file/archive) | |
version: header.subarray(4, 8), // versinn of archive used | |
compression_type: header.subarray(8, 12).toString(), //parse to string (type of compression used) | |
toc_length: toDecString(12, 16), | |
toc_entry_size: toDecString(16, 20), | |
toc_entries: toDecString(20, 24), | |
block_size: fromBinarytoDecString(24, 28), | |
archive_flags: fromBinarytoDecString(28, 32), | |
name_digest: header.subarray(32, 48).toString(), | |
block_offset: fromBinarytoDecString(48, 52), | |
uncompressed_size: toDecString(52, 57), | |
file_offset: toDecString(57, 62), | |
}; | |
console.log(header_data); | |
}); | |
return decode; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
magic: 'PSAR', | |
version: <Buffer 00 01 00 04>, | |
compression_type: 'zlib', | |
toc_length: 82264, | |
toc_entry_size: 48, | |
toc_entries: 265, | |
block_size: 65536, | |
archive_flags: 1, | |
name_digest: '\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00', | |
block_offset: 0, | |
uncompressed_size: 9257, | |
file_offset: 82264 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment