Skip to main content

nms_save/
lib.rs

1//! Raw binary save file parser for No Man's Sky.
2//!
3//! Reads `save.hg` files directly from disk:
4//!
5//! 1. Detect format (plaintext JSON vs LZ4 compressed)
6//! 2. Parse sequential LZ4 blocks (magic `0xFEEDA1E5`), decompress, concatenate
7//! 3. Deobfuscate JSON keys using MBINCompiler's `mapping.json`
8//! 4. Deserialize into typed Rust structs via serde
9//!
10//! Also handles metadata verification (`mf_save.hg`) via XXTEA + SHA-256.
11
12pub mod convert;
13pub mod decompress;
14pub mod error;
15pub mod locate;
16pub mod mapping;
17pub mod metadata;
18pub mod model;
19pub mod xxtea;
20
21pub use decompress::{SaveFormat, decompress_save, decompress_save_file, detect_format};
22pub use error::SaveError;
23pub use mapping::{KeyMapping, deobfuscate_json, is_obfuscated};
24pub use metadata::{SaveMetadata, StorageSlot, read_metadata, verify_sha256};
25pub use model::SaveRoot;
26
27/// Parse deobfuscated save file JSON bytes into a [`SaveRoot`] struct.
28///
29/// The input must be valid UTF-8 JSON with plaintext (deobfuscated) keys.
30pub fn parse_save(json: &[u8]) -> Result<SaveRoot, SaveError> {
31    serde_json::from_slice(json).map_err(|e| SaveError::JsonParseError {
32        message: e.to_string(),
33    })
34}
35
36/// Parse a deobfuscated save file from disk.
37///
38/// Reads the file and deserializes it. Assumes the file is already
39/// decompressed and deobfuscated JSON.
40pub fn parse_save_file(path: &std::path::Path) -> Result<SaveRoot, SaveError> {
41    let bytes = std::fs::read(path)?;
42    parse_save(&bytes)
43}