diff options
Diffstat (limited to 'src/main.rs')
-rw-r--r-- | src/main.rs | 91 |
1 files changed, 70 insertions, 21 deletions
diff --git a/src/main.rs b/src/main.rs index c1dcfd2..a0b35c3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,9 +2,10 @@ use log::debug; use std::{ env::args, fs::File, - io::{BufReader, Read}, + io::{BufReader, Cursor, Read}, }; use unity_tools::{ + common_strings::COMMON_STRINGS, helper::{Endianness, ReadExt}, unityfs::UnityFS, }; @@ -20,7 +21,7 @@ fn main() -> anyhow::Result<()> { } let mut cab = fs.read(&node)?; // let mut writer = File::create(format!("/tmp/{}", node.name))?; - // copy(&mut cab, &mut writer)?; + // std::io::copy(&mut cab, &mut writer)?; // continue; let mut metadata_size = cab.read_u32_be()?; @@ -54,39 +55,74 @@ fn main() -> anyhow::Result<()> { let has_type_trees = cab.read_u8()? != 0; let num_types = cab.read_u32(e)?; + debug!("has_type_trees={has_type_trees:?}"); + debug!("num_types={num_types}"); for _ in 0..num_types { - let mut class_id = cab.read_i32(e)?; + let class_id = cab.read_i32(e)?; let stripped_type = cab.read_u8()? != 0; - let script_id = cab.read_i16(e)?; + let script_index = cab.read_i16(e)?; + let mut script_id = 0; + // TODO reftype if class_id == 114 { - if script_id >= 0 { - class_id = -2 - script_id as i32; - } else { - class_id = -1; - } + script_id = cab.read_u128_be()?; } + let _old_hash = cab.read_u128_be()?; + eprintln!("class_id={class_id}"); eprintln!("stripped_type={stripped_type}"); + eprintln!("script_index={script_index}"); eprintln!("script_id={script_id}"); - let hash = if class_id < 0 { - (cab.read_u128_be()?, cab.read_u128_be()?) - } else { - (cab.read_u128_be()?, 0) - }; - eprintln!("{hash:032x?}"); - if has_type_trees { let num_nodes = cab.read_u32(e)?; - eprintln!("tree:num_nodes={num_nodes}"); let size = cab.read_u32(e)?; - assert!(format >= 19); + eprintln!("tree:num_nodes={num_nodes}"); + eprintln!("tree:size={size}"); + + let mut node_data = vec![0u8; num_nodes as usize * 32]; + cab.read_exact(&mut node_data)?; + let mut node_data = Cursor::new(node_data); + let mut string_data = vec![0u8; size as usize]; + cab.read_exact(&mut string_data)?; + + let get_string = |off: u32| { + let data = if off & 0x80000000 != 0 { + let off = off & 0x7fffffff; + &COMMON_STRINGS[(off & 0x7fffffff) as usize..] + } else { + &string_data[off as usize..] + }; + String::from_utf8( + data.iter() + .copied() + .take_while(|e| *e != 0) + .collect::<Vec<u8>>(), + ) + }; + + let mut nodes = Vec::new(); for _ in 0..num_nodes { - cab.read_u32(e)?; + nodes.push(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)?, + }); + } + eprintln!("{nodes:#?}"); + + if format >= 21 { + let num_deps = cab.read_u32(e)?; + for _ in 0..num_deps { + cab.read_u32(e)?; + } } - let mut data = vec![0u8; size as usize]; - cab.read_exact(&mut data)?; } if format > 21 { @@ -101,3 +137,16 @@ fn main() -> anyhow::Result<()> { Ok(()) } + +#[derive(Debug)] +struct TypeTreeNode { + version: u16, + level: u8, + type_flags: u8, + type_string: String, + name_string: String, + byte_size: i32, + index: i32, + flags: i32, + ref_type_hash: u64, +} |