RustyAssetBundleEXtractor (rabex)

A crate for working with Unity Engine asset files. It supports reading and writing bundle files and serialized files, as well as reading typetrees with serde integration.
Maintained fork of UniversalGameExtraction/RustyAssetBundleEXtractor, and source of the rabex crate on crates.io.
Features
- parsing and writing of unity serializedfiles (
level0, globalgamemanagers, resources.assets)
- parsing and writing of unity bundle files (
data.unity3d, assetbundle.bundle, e.g. used by addressables)
- serde [de]serialization of objects using typetrees
- an embedded listing of builtin typetrees using https://github.com/AssetRipper/Tpk
Examples
Parsing an AssetBundle and dumping its objects
use std::collections::HashMap;
use std::fs::File;
use std::io::{BufReader, Cursor};
use std::path::Path;
use anyhow::Result;
use rabex::files::SerializedFile;
use rabex::files::bundlefile::{BundleFileReader, ExtractionConfig};
use rabex::objects::{ClassId, PPtr};
use rabex::tpk::TpkTypeTreeBlob;
use rabex::typetree::typetree_cache::sync::TypeTreeCache;
use serde_derive::Deserialize;
fn main() -> Result<()> {
let tpk = TypeTreeCache::new(TpkTypeTreeBlob::embedded());
let path = std::env::args()
.nth(1)
.ok_or_else(|| anyhow::anyhow!("Expected path to unity bundle argument"))?;
let config = ExtractionConfig::default().assume_recent_unity();
let mut reader = BufReader::new(File::open(path)?);
let mut bundle = BundleFileReader::from_reader(&mut reader, &config)?;
let export_dir = Path::new("out");
std::fs::create_dir_all(&export_dir)?;
while let Some(mut file) = bundle.next_serialized() {
let data = file.read()?;
let reader = &mut Cursor::new(data);
let serialized = SerializedFile::from_reader(reader)?;
println!(
"Contains typetree information: {}",
serialized.m_EnableTypeTree
);
for object in serialized.objects() {
println!("{:?} at {}", object.m_ClassID, object.m_PathID);
let data = serialized.read::<serde_json::Value>(object, &tpk, reader)?;
let name = data["m_Name"].as_str().unwrap();
let object_path = export_dir.join(name);
std::fs::write(object_path, serde_json::to_string_pretty(&data)?)?;
if object.m_ClassID == ClassId::AssetBundle {
let asset_bundle = serialized.read::<AssetBundle>(object, &tpk, reader)?;
println!("Asset Bundle: {:#?}", asset_bundle);
}
}
}
Ok(())
}
#[derive(Debug, Deserialize, Default)]
#[allow(non_snake_case)]
pub struct AssetBundle {
pub m_Name: String,
pub m_PreloadTable: Vec<PPtr>,
pub m_AssetBundleName: String,
pub m_IsStreamedSceneAssetBundle: bool,
pub m_SceneHashes: HashMap<String, String>,
}
Creating an assetbundle from scratch using BundleFileBuilder and SerializedFileBuilder
examples/create_assetbundle.rs
Related Projects
- rabex-env: Higher-level wrapper around this crate, with support for resolving
PPtr dependencies through different files, centered around the Environment abstraction.
- unity-scene-repacker: Command line tool for repacking unity scenes and asset bundles into distilled versions suitable for loading certain objects in mods
- steam-multiversion-viewer: [wip] Visual exploration tool for steam game versions, with support for reading and structurally diffing unity game files.
License
RustyAssetBundleEXtractor is licensed under either of Apache License, Version 2.0 or MIT license
at your option.