aboutsummaryrefslogtreecommitdiff
path: root/src/main.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/main.rs')
-rw-r--r--src/main.rs91
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,
+}