3 releases
0.0.3 | Jul 4, 2023 |
---|---|
0.0.2 | Jul 4, 2023 |
0.0.1 | Jun 30, 2023 |
#657 in Game dev
1MB
12K
SLoC
UnityRustEXtractor
A work-in-progress extractor and patcher for Unity Engine asset files. Currently it can do about nothing, so please check back later.
Dependencies
This projects uses following dependencies:
-
Compression & Decompression:
-
Other:
Examples
parsing a normal BundleFile and dumping its objects
use std::{
fs::{DirBuilder, File},
io::{Seek, Write},
path::Path,
};
use urex::files::{BundleFile, SerializedFile};
use urex::config::ExtractionConfig;
let mut reader = File::open(fp).unwrap();
let export_dir = Path::new("dump");
// parse the bundle file
let config = ExtractionConfig::new();
let mut bundle = BundleFile::from_reader(&mut reader, &config).unwrap();
// iterate over the files in the bundle
for directory in &bundle.m_DirectoryInfo {
// generate export dir for cab
let export_cab_dir = export_dir.join(&directory.path);
// seek to the start of the file in the bundle
bundle
.m_BlockReader
.seek(std::io::SeekFrom::Start(directory.offset as u64))
.unwrap();
// try to parse the file as a SerializedFile
match SerializedFile::from_reader(&mut bundle.m_BlockReader, &config) {
Ok(serialized) => {
// iterate over objects
for object in &serialized.m_Objects {
// get a helper object to parse the object
let mut handler =
serialized.get_object_handler(object, &mut bundle.m_BlockReader);
// try to get the name
let name = match handler.peak_name() {
Ok(name) => format!("{}_{}", object.m_PathID, name),
Err(_) => format!("{}", object.m_PathID),
};
// ensure that the parent directory exists
let dst_path = export_cab_dir.join(name);
DirBuilder::new()
.recursive(true)
.create(dst_path.parent().unwrap())
.unwrap_or_else(|_| panic!("Failed to create {:?}", dst_path.parent()));
// parse the object as json
let json = handler.parse_as_json().unwrap();
// println!("{:?}", json);
File::create(format!("{}.json", dst_path.to_string_lossy()))
.unwrap()
.write_all(json.to_string().as_bytes())
.unwrap();
// parse the object as yaml
let yaml = handler.parse_as_yaml().unwrap().unwrap();
// println!("{:?}", yaml);
File::create(format!("{}.yaml", dst_path.to_string_lossy()))
.unwrap()
.write_all(serde_yaml::to_string(&yaml).unwrap().as_bytes())
.unwrap();
// parse the object as msgpack
let msgpack = handler.parse_as_msgpack().unwrap();
File::create(format!("{}.msgpack", dst_path.to_string_lossy()))
.unwrap()
.write_all(&msgpack)
.unwrap();
// serialize as actual class
// note: a small part of the object classes isn't implemented yet
if object.m_ClassID == urex::objects::map::AssetBundle {
let ab = handler
.parse::<urex::objects::classes::AssetBundle>()
.unwrap();
println!("{:?}", ab);
}
}
}
Err(e) => {
// TODO - try to filter out resource files
println!(
"Failed to parse {} as SerializedFile.",
&directory.path.to_string()
);
}
}
}
parsing a by UnityCN encrypted BundleFile and handling stripped Unity version
let mut reader = File::open(fp).unwrap();
let config = ExtractionConfig {
unitycn_key: Some("Decryption Key".as_bytes().try_into().unwrap()),
fallback_unity_version: "2020.3.0f1".to_owned(),
};
let bundle = crate::files::BundleFile::from_reader(&mut reader, &config).unwrap();
reading a UnityCN encrypted BundleFile
Notes
TODO
-
Parsers:
- WebFile
- SerializedFile
-
Object Classes:
- Generator
- Parser
- Writer
- Export Functions
-
Tests:
- Normal Tests
- Artificing Test Files
- 100% Coverage
-
Other:
- feature config
Getting Help
TODO:
- Docs
- GitHub Issues and Discussion
- Discord server
Contributing
See CONTRIBUTING.md.
License
UnityRustEXtractor is primarily distributed under the terms of both the MIT license and the Apache License (Version 2.0).
See LICENSE-APACHE, LICENSE-MIT, and COPYRIGHT for details.
Dependencies
~13MB
~394K SLoC