diff options
author | metamuffin <metamuffin@disroot.org> | 2025-03-13 19:56:15 +0100 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2025-03-13 19:56:15 +0100 |
commit | d3006b6d05f7995c6a49d67401293f1266b3ea1f (patch) | |
tree | 04541847c9fec65091a10c586c237ffd835e67c1 | |
parent | 58186bb96e38b92e426e75e08b0e0c95d05d319c (diff) | |
download | unity-tools-d3006b6d05f7995c6a49d67401293f1266b3ea1f.tar unity-tools-d3006b6d05f7995c6a49d67401293f1266b3ea1f.tar.bz2 unity-tools-d3006b6d05f7995c6a49d67401293f1266b3ea1f.tar.zst |
move SerializedFile functions to impl
-rw-r--r-- | src/bin/gltf.rs | 4 | ||||
-rw-r--r-- | src/bin/json.rs | 6 | ||||
-rw-r--r-- | src/bin/meshes.rs | 4 | ||||
-rw-r--r-- | src/bin/probe.rs | 4 | ||||
-rw-r--r-- | src/bin/textures.rs | 4 | ||||
-rw-r--r-- | src/bin/typegraph.rs | 4 | ||||
-rw-r--r-- | src/bin/yaml.rs | 5 | ||||
-rw-r--r-- | src/serialized_file.rs | 389 |
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 { |