aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormetamuffin <metamuffin@disroot.org>2025-03-13 19:56:15 +0100
committermetamuffin <metamuffin@disroot.org>2025-03-13 19:56:15 +0100
commitd3006b6d05f7995c6a49d67401293f1266b3ea1f (patch)
tree04541847c9fec65091a10c586c237ffd835e67c1 /src
parent58186bb96e38b92e426e75e08b0e0c95d05d319c (diff)
downloadunity-tools-d3006b6d05f7995c6a49d67401293f1266b3ea1f.tar
unity-tools-d3006b6d05f7995c6a49d67401293f1266b3ea1f.tar.bz2
unity-tools-d3006b6d05f7995c6a49d67401293f1266b3ea1f.tar.zst
move SerializedFile functions to impl
Diffstat (limited to 'src')
-rw-r--r--src/bin/gltf.rs4
-rw-r--r--src/bin/json.rs6
-rw-r--r--src/bin/meshes.rs4
-rw-r--r--src/bin/probe.rs4
-rw-r--r--src/bin/textures.rs4
-rw-r--r--src/bin/typegraph.rs4
-rw-r--r--src/bin/yaml.rs5
-rw-r--r--src/serialized_file.rs389
8 files changed, 210 insertions, 210 deletions
diff --git a/src/bin/gltf.rs b/src/bin/gltf.rs
index 18d406a..07adec6 100644
--- a/src/bin/gltf.rs
+++ b/src/bin/gltf.rs
@@ -8,7 +8,7 @@ use std::{
use unity_tools::{
classes::mesh::{Mesh, VertexDataChannel},
object::{parser::FromValue, read::read_value},
- serialized_file::read_serialized_file,
+ serialized_file::SerializedFile,
unityfs::UnityFS,
};
@@ -27,7 +27,7 @@ fn main() -> anyhow::Result<()> {
.to_owned();
let mut cab = fs.read(&cabfile)?;
- let file = read_serialized_file(&mut cab)?;
+ let file = SerializedFile::read(&mut cab)?;
for ob in file.objects {
cab.seek(SeekFrom::Start(ob.data_offset))?;
let typetree = if ob.type_id < 0 {
diff --git a/src/bin/json.rs b/src/bin/json.rs
index d669148..2d09306 100644
--- a/src/bin/json.rs
+++ b/src/bin/json.rs
@@ -3,9 +3,7 @@ use std::{
fs::File,
io::{BufReader, Seek, SeekFrom, stdout},
};
-use unity_tools::{
- object::read::read_value, serialized_file::read_serialized_file, unityfs::UnityFS,
-};
+use unity_tools::{object::read::read_value, serialized_file::SerializedFile, unityfs::UnityFS};
fn main() -> anyhow::Result<()> {
env_logger::init_from_env("LOG");
@@ -16,7 +14,7 @@ fn main() -> anyhow::Result<()> {
let node = fs.find_main_file().unwrap().to_owned();
let mut cab = fs.read(&node)?;
- let file = read_serialized_file(&mut cab)?;
+ let file = SerializedFile::read(&mut cab)?;
for ob in file.objects {
cab.seek(SeekFrom::Start(ob.data_offset))?;
let typetree = if ob.type_id < 0 {
diff --git a/src/bin/meshes.rs b/src/bin/meshes.rs
index 953f2c1..f2b4edf 100644
--- a/src/bin/meshes.rs
+++ b/src/bin/meshes.rs
@@ -8,7 +8,7 @@ use std::{
use unity_tools::{
classes::mesh::{Mesh, VertexDataChannel},
object::{parser::FromValue, read::read_value},
- serialized_file::read_serialized_file,
+ serialized_file::SerializedFile,
unityfs::UnityFS,
};
@@ -29,7 +29,7 @@ fn main() -> anyhow::Result<()> {
.to_owned();
let mut cab = fs.read(&cabfile)?;
- let file = read_serialized_file(&mut cab)?;
+ let file = SerializedFile::read(&mut cab)?;
for ob in file.objects {
cab.seek(SeekFrom::Start(ob.data_offset))?;
let typetree = if ob.type_id < 0 {
diff --git a/src/bin/probe.rs b/src/bin/probe.rs
index 6f46c0a..feca633 100644
--- a/src/bin/probe.rs
+++ b/src/bin/probe.rs
@@ -1,6 +1,6 @@
use anyhow::Result;
use std::{env::args, fs::File, io::BufReader};
-use unity_tools::{serialized_file::read_serialized_file_header, unityfs::UnityFS};
+use unity_tools::{serialized_file::SerializedFileHeader, unityfs::UnityFS};
fn main() -> Result<()> {
let file = BufReader::new(File::open(args().nth(1).unwrap())?);
@@ -8,7 +8,7 @@ fn main() -> Result<()> {
let node = fs.find_main_file().unwrap().to_owned();
let mut cab = fs.read(&node)?;
- let ch = read_serialized_file_header(&mut cab)?;
+ let ch = SerializedFileHeader::read(&mut cab)?;
if fs.unity_version.is_ascii() && ch.generator_version.is_ascii() && ch.format < 100 {
println!(
diff --git a/src/bin/textures.rs b/src/bin/textures.rs
index 209e23c..6ceabac 100644
--- a/src/bin/textures.rs
+++ b/src/bin/textures.rs
@@ -8,7 +8,7 @@ use std::{
use unity_tools::{
classes::texture2d::Texture2D,
object::{parser::FromValue, read::read_value},
- serialized_file::read_serialized_file,
+ serialized_file::SerializedFile,
unityfs::UnityFS,
};
@@ -27,7 +27,7 @@ fn main() -> anyhow::Result<()> {
.to_owned();
let mut cab = fs.read(&cabfile)?;
- let file = read_serialized_file(&mut cab)?;
+ let file = SerializedFile::read(&mut cab)?;
for ob in file.objects {
cab.seek(SeekFrom::Start(ob.data_offset))?;
let typetree = if ob.type_id < 0 {
diff --git a/src/bin/typegraph.rs b/src/bin/typegraph.rs
index b8e26d2..7425778 100644
--- a/src/bin/typegraph.rs
+++ b/src/bin/typegraph.rs
@@ -6,7 +6,7 @@ use std::{
io::BufReader,
};
use unity_tools::{
- serialized_file::{TypeTreeNode, read_serialized_file},
+ serialized_file::{SerializedFile, TypeTreeNode},
unityfs::UnityFS,
};
@@ -19,7 +19,7 @@ fn main() -> anyhow::Result<()> {
let mut edges = BTreeSet::new();
let node = fs.find_main_file().unwrap().to_owned();
let mut cab = fs.read(&node)?;
- let file = read_serialized_file(&mut cab)?;
+ let file = SerializedFile::read(&mut cab)?;
for ob in file.objects {
let typetree = if ob.type_id < 0 {
diff --git a/src/bin/yaml.rs b/src/bin/yaml.rs
index 2899c4c..fd3eec6 100644
--- a/src/bin/yaml.rs
+++ b/src/bin/yaml.rs
@@ -5,8 +5,7 @@ use std::{
io::{BufReader, Seek, SeekFrom, stdout},
};
use unity_tools::{
- classes::HValue, object::read::read_value, serialized_file::read_serialized_file,
- unityfs::UnityFS,
+ classes::HValue, object::read::read_value, serialized_file::SerializedFile, unityfs::UnityFS,
};
fn main() -> anyhow::Result<()> {
@@ -18,7 +17,7 @@ fn main() -> anyhow::Result<()> {
let node = fs.find_main_file().unwrap().to_owned();
let mut cab = fs.read(&node)?;
- let file = read_serialized_file(&mut cab)?;
+ let file = SerializedFile::read(&mut cab)?;
for ob in file.objects {
cab.seek(SeekFrom::Start(ob.data_offset))?;
let typetree = if ob.type_id < 0 {
diff --git a/src/serialized_file.rs b/src/serialized_file.rs
index 3570a91..b56fa3a 100644
--- a/src/serialized_file.rs
+++ b/src/serialized_file.rs
@@ -76,229 +76,232 @@ pub struct SerializedFileHeader {
pub target_platform: u32,
}
-pub fn read_serialized_file_header(mut file: impl Read + Seek) -> Result<SerializedFileHeader> {
- let mut metadata_size = file.read_u32_be()?;
- let mut file_size = file.read_u32_be()? as u64;
- let format = file.read_u32_be()?;
- let mut data_offset = file.read_u32_be()? as u64;
+impl SerializedFileHeader {
+ pub fn read(mut file: impl Read + Seek) -> Result<Self> {
+ let mut metadata_size = file.read_u32_be()?;
+ let mut file_size = file.read_u32_be()? as u64;
+ let format = file.read_u32_be()?;
+ let mut data_offset = file.read_u32_be()? as u64;
- if format >= 1000 {
- bail!("bad format version {format:x}")
- }
- info!("File format version: {format}");
+ if format >= 1000 {
+ bail!("bad format version {format:x}")
+ }
+ info!("File format version: {format}");
- assert!(format >= 9);
- let e = match file.read_u32_be()? {
- 0 => Endianness::Little,
- _ => Endianness::Big,
- };
- debug!("endianess={e:?}");
+ assert!(format >= 9);
+ let e = match file.read_u32_be()? {
+ 0 => Endianness::Little,
+ _ => Endianness::Big,
+ };
+ debug!("endianess={e:?}");
- if format >= 22 {
- metadata_size = file.read_u32_be()?;
- file_size = file.read_u64_be()?;
- data_offset = file.read_u64_be()?;
- file.read_u64_be()?;
- }
- debug!("metadata_size={metadata_size}");
- debug!("file_size={file_size}");
- debug!("data_offset={data_offset}");
+ if format >= 22 {
+ metadata_size = file.read_u32_be()?;
+ file_size = file.read_u64_be()?;
+ data_offset = file.read_u64_be()?;
+ file.read_u64_be()?;
+ }
+ debug!("metadata_size={metadata_size}");
+ debug!("file_size={file_size}");
+ debug!("data_offset={data_offset}");
- let generator_version = file.read_cstr()?;
- let target_platform = file.read_u32_le()?;
- info!("Generator version: {generator_version:?}");
- debug!("target_platform={target_platform}");
- Ok(SerializedFileHeader {
- data_offset,
- _file_size: file_size,
- endianness: e,
- format,
- _metadata_size: metadata_size,
- target_platform,
- generator_version,
- })
+ let generator_version = file.read_cstr()?;
+ let target_platform = file.read_u32_le()?;
+ info!("Generator version: {generator_version:?}");
+ debug!("target_platform={target_platform}");
+ Ok(Self {
+ data_offset,
+ _file_size: file_size,
+ endianness: e,
+ format,
+ _metadata_size: metadata_size,
+ target_platform,
+ generator_version,
+ })
+ }
}
+impl SerializedFile {
+ pub fn read(mut file: impl Read + Seek) -> Result<SerializedFile> {
+ let h = SerializedFileHeader::read(&mut file)?;
+ let e = h.endianness;
-pub fn read_serialized_file(mut file: impl Read + Seek) -> Result<SerializedFile> {
- let h = read_serialized_file_header(&mut file)?;
- let e = h.endianness;
+ let has_type_trees = file.read_u8()? != 0;
+ let num_types = file.read_u32(e)?;
+ debug!("has_type_trees={has_type_trees:?}");
+ debug!("num_types={num_types}");
- let has_type_trees = file.read_u8()? != 0;
- let num_types = file.read_u32(e)?;
- debug!("has_type_trees={has_type_trees:?}");
- debug!("num_types={num_types}");
+ let mut types = Vec::new();
- let mut types = Vec::new();
-
- for _ in 0..num_types {
- let class_id = file.read_i32(e)?;
- let stripped_type = file.read_u8()? != 0;
- let script_type_index = file.read_i16(e)?;
- let mut script_id = 0;
- // TODO reftype
- if class_id == 114 {
- script_id = file.read_u128_be()?;
- }
- let _old_hash = file.read_u128_be()?;
+ for _ in 0..num_types {
+ let class_id = file.read_i32(e)?;
+ let stripped_type = file.read_u8()? != 0;
+ let script_type_index = file.read_i16(e)?;
+ let mut script_id = 0;
+ // TODO reftype
+ if class_id == 114 {
+ script_id = file.read_u128_be()?;
+ }
+ let _old_hash = file.read_u128_be()?;
- trace!("class_id={class_id}");
- trace!("stripped_type={stripped_type}");
- trace!("script_type_index={script_type_index}");
- trace!("script_id={script_id}");
+ trace!("class_id={class_id}");
+ trace!("stripped_type={stripped_type}");
+ trace!("script_type_index={script_type_index}");
+ trace!("script_id={script_id}");
- let mut type_deps = Vec::new();
- let mut type_tree = None;
- if has_type_trees {
- let num_nodes = file.read_u32(e)?;
- let size = file.read_u32(e)?;
- trace!("tree:num_nodes={num_nodes}");
- trace!("tree:size={size}");
+ let mut type_deps = Vec::new();
+ let mut type_tree = None;
+ if has_type_trees {
+ let num_nodes = file.read_u32(e)?;
+ let size = file.read_u32(e)?;
+ trace!("tree:num_nodes={num_nodes}");
+ trace!("tree:size={size}");
- let mut node_data = vec![0u8; num_nodes as usize * 32];
- file.read_exact(&mut node_data)?;
- let mut node_data = Cursor::new(node_data);
- let mut string_data = vec![0u8; size as usize];
- file.read_exact(&mut string_data)?;
+ let mut node_data = vec![0u8; num_nodes as usize * 32];
+ file.read_exact(&mut node_data)?;
+ let mut node_data = Cursor::new(node_data);
+ let mut string_data = vec![0u8; size as usize];
+ file.read_exact(&mut string_data)?;
- let get_string = |off: u32| {
- let data = if off & 0x80000000 != 0 {
- let off = off & 0x7fffffff;
- if off as usize > COMMON_STRINGS.len() {
- warn!("common strings missing index {off:08x}");
- b"<common string missing>"
+ let get_string = |off: u32| {
+ let data = if off & 0x80000000 != 0 {
+ let off = off & 0x7fffffff;
+ if off as usize > COMMON_STRINGS.len() {
+ warn!("common strings missing index {off:08x}");
+ b"<common string missing>"
+ } else {
+ &COMMON_STRINGS[off as usize..]
+ }
} else {
- &COMMON_STRINGS[off as usize..]
- }
- } else {
- &string_data[off as usize..]
+ &string_data[off as usize..]
+ };
+ String::from_utf8(
+ data.iter()
+ .copied()
+ .take_while(|e| *e != 0)
+ .collect::<Vec<u8>>(),
+ )
};
- String::from_utf8(
- data.iter()
- .copied()
- .take_while(|e| *e != 0)
- .collect::<Vec<u8>>(),
- )
- };
- let mut parents: Vec<TypeTreeNode> = vec![];
- for _ in 0..num_nodes {
- let node = TypeTreeNode {
- version: node_data.read_u16(e)?,
- level: node_data.read_u8()?,
- type_flags: node_data.read_u8()?,
- type_string: get_string(node_data.read_u32(e)?)?,
- name_string: get_string(node_data.read_u32(e)?)?,
- byte_size: node_data.read_i32(e)?,
- index: node_data.read_i32(e)?,
- flags: node_data.read_i32(e)?,
- ref_type_hash: node_data.read_u64(e)?,
- children: vec![],
- };
- if node.level == 0 && !parents.is_empty() {
- warn!("unexpected toplevel typetree node");
- parents.clear();
+ let mut parents: Vec<TypeTreeNode> = vec![];
+ for _ in 0..num_nodes {
+ let node = TypeTreeNode {
+ version: node_data.read_u16(e)?,
+ level: node_data.read_u8()?,
+ type_flags: node_data.read_u8()?,
+ type_string: get_string(node_data.read_u32(e)?)?,
+ name_string: get_string(node_data.read_u32(e)?)?,
+ byte_size: node_data.read_i32(e)?,
+ index: node_data.read_i32(e)?,
+ flags: node_data.read_i32(e)?,
+ ref_type_hash: node_data.read_u64(e)?,
+ children: vec![],
+ };
+ if node.level == 0 && !parents.is_empty() {
+ warn!("unexpected toplevel typetree node");
+ parents.clear();
+ }
+ while parents.len() > node.level as usize {
+ let n = parents.pop().unwrap();
+ parents.last_mut().unwrap().children.push(n)
+ }
+ parents.push(node);
}
- while parents.len() > node.level as usize {
+ while parents.len() > 1 {
let n = parents.pop().unwrap();
parents.last_mut().unwrap().children.push(n)
}
- parents.push(node);
- }
- while parents.len() > 1 {
- let n = parents.pop().unwrap();
- parents.last_mut().unwrap().children.push(n)
- }
- type_tree = parents.pop();
+ type_tree = parents.pop();
- if h.format >= 21 {
- let num_deps = file.read_u32(e)?;
- trace!("num_deps={num_deps}");
- for _ in 0..num_deps {
- type_deps.push(file.read_u32(e)?);
+ if h.format >= 21 {
+ let num_deps = file.read_u32(e)?;
+ trace!("num_deps={num_deps}");
+ for _ in 0..num_deps {
+ type_deps.push(file.read_u32(e)?);
+ }
}
}
- }
- types.push(SeralizedType {
- class_id,
- script_id,
- script_type_index,
- stripped_type,
- type_deps,
- type_tree,
- })
- }
+ types.push(SeralizedType {
+ class_id,
+ script_id,
+ script_type_index,
+ stripped_type,
+ type_deps,
+ type_tree,
+ })
+ }
- let num_objects = file.read_u32(e)?;
- debug!("num_objects={num_objects}");
- let mut objects = Vec::new();
- for _ in 0..num_objects {
- file.align(4)?;
- let path_id = file.read_i64(e)?;
- let data_offset = if h.format >= 22 {
- file.read_u64(e)?
- } else {
- file.read_u32(e)? as u64
- } + h.data_offset;
- let data_size = file.read_u32(e)?;
- let type_id = file.read_i32(e)?;
- objects.push(ObjectInfo {
- data_offset,
- data_size,
- path_id,
- type_id,
- })
- }
+ let num_objects = file.read_u32(e)?;
+ debug!("num_objects={num_objects}");
+ let mut objects = Vec::new();
+ for _ in 0..num_objects {
+ file.align(4)?;
+ let path_id = file.read_i64(e)?;
+ let data_offset = if h.format >= 22 {
+ file.read_u64(e)?
+ } else {
+ file.read_u32(e)? as u64
+ } + h.data_offset;
+ let data_size = file.read_u32(e)?;
+ let type_id = file.read_i32(e)?;
+ objects.push(ObjectInfo {
+ data_offset,
+ data_size,
+ path_id,
+ type_id,
+ })
+ }
- let num_scripts = file.read_u32(e)?;
- debug!("num_scripts={num_scripts}");
- let mut scripts = Vec::new();
- for _ in 0..num_scripts {
- let file_index = file.read_u32(e)?;
- file.align(4)?;
- let identifier = file.read_i64(e)?;
- scripts.push(Script {
- file_index,
- identifier,
- })
- }
+ let num_scripts = file.read_u32(e)?;
+ debug!("num_scripts={num_scripts}");
+ let mut scripts = Vec::new();
+ for _ in 0..num_scripts {
+ let file_index = file.read_u32(e)?;
+ file.align(4)?;
+ let identifier = file.read_i64(e)?;
+ scripts.push(Script {
+ file_index,
+ identifier,
+ })
+ }
- let num_externals = file.read_u32(e)?;
- debug!("num_externals={num_externals}");
- let mut externals = Vec::new();
- for _ in 0..num_externals {
- let something = file.read_cstr()?;
- let guid = file.read_u128_be()?;
- let r#type = file.read_i32(e)?;
- let path_name = file.read_cstr()?;
- externals.push(External {
- guid,
- path_name,
- something,
- r#type,
- })
- }
+ let num_externals = file.read_u32(e)?;
+ debug!("num_externals={num_externals}");
+ let mut externals = Vec::new();
+ for _ in 0..num_externals {
+ let something = file.read_cstr()?;
+ let guid = file.read_u128_be()?;
+ let r#type = file.read_i32(e)?;
+ let path_name = file.read_cstr()?;
+ externals.push(External {
+ guid,
+ path_name,
+ something,
+ r#type,
+ })
+ }
- if h.format >= 20 {
- let num_ref_types = file.read_i32(e)?;
- debug!("num_ref_types={num_ref_types}");
- // let mut ref_types = Vec::new();
- for _ in 0..num_ref_types {
- todo!()
+ if h.format >= 20 {
+ let num_ref_types = file.read_i32(e)?;
+ debug!("num_ref_types={num_ref_types}");
+ // let mut ref_types = Vec::new();
+ for _ in 0..num_ref_types {
+ todo!()
+ }
}
- }
- let user_string = file.read_cstr()?;
+ let user_string = file.read_cstr()?;
- Ok(SerializedFile {
- header: h,
- types,
- externals,
- endianness: e,
- objects,
- scripts,
- user_string,
- })
+ Ok(SerializedFile {
+ header: h,
+ types,
+ externals,
+ endianness: e,
+ objects,
+ scripts,
+ user_string,
+ })
+ }
}
impl TypeTreeNode {