aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/bin/parse.rs31
-rw-r--r--src/helper.rs2
-rw-r--r--src/object.rs21
-rw-r--r--src/unityfs.rs2
4 files changed, 51 insertions, 5 deletions
diff --git a/src/bin/parse.rs b/src/bin/parse.rs
index c0cb0e5..273cffd 100644
--- a/src/bin/parse.rs
+++ b/src/bin/parse.rs
@@ -4,7 +4,11 @@ use std::{
fs::File,
io::{BufReader, Read, Seek, SeekFrom},
};
-use unity_tools::{object::read_value, serialized_file::read_serialized_file, unityfs::UnityFS};
+use unity_tools::{
+ object::{Value, read_value},
+ serialized_file::{TypeTreeNode, read_serialized_file},
+ unityfs::UnityFS,
+};
fn main() -> anyhow::Result<()> {
env_logger::init_from_env("LOG");
@@ -36,10 +40,35 @@ fn main() -> anyhow::Result<()> {
// .expect("unknown type")
&file.types[ob.type_id as usize]
};
+ // fn print_types(tt: &TypeTreeNode) {
+ // println!("{}", tt.type_string);
+ // for c in &tt.children {
+ // print_types(&c);
+ // }
+ // }
+ // fn print_crit_types(tt: &TypeTreeNode) {
+ // let mut crit = tt.byte_size == -1;
+ // for c in &tt.children {
+ // print_crit_types(&c);
+ // crit &= c.byte_size != -1
+ // }
+ // if crit {
+ // println!("{}", tt.type_string);
+ // }
+ // }
+ if let Some(tree) = &typetree.type_tree {
+ println!("{}", tree.type_string);
+ // print_crit_types(tree);
+ // print_types(tree);
+ }
// eprintln!("{typetree:#?}");
let value = read_value(typetree.type_tree.as_ref().unwrap(), e, &mut cab)?;
+ // if let Value::Object { class, .. } = &value {
+ // println!("{class}")
+ // }
+
debug!(
"{}",
serde_json::to_string_pretty(&value.to_json()).unwrap()
diff --git a/src/helper.rs b/src/helper.rs
index aada1fd..48f3d2d 100644
--- a/src/helper.rs
+++ b/src/helper.rs
@@ -1,3 +1,4 @@
+use log::trace;
use std::io::{Read, Result, Seek};
#[derive(Debug, Clone, Copy, PartialEq)]
@@ -196,6 +197,7 @@ impl<T: Seek> AlignExt for T {
fn align(&mut self, size: u64) -> Result<()> {
let off = self.stream_position()? % size;
if off != 0 {
+ trace!("align to {size} (+{})", size - off);
self.seek_relative((size - off) as i64)?;
}
Ok(())
diff --git a/src/object.rs b/src/object.rs
index ab27ea4..bdaf3ec 100644
--- a/src/object.rs
+++ b/src/object.rs
@@ -1,6 +1,6 @@
use crate::helper::{AlignExt, Endianness, ReadExt};
use crate::serialized_file::TypeTreeNode;
-use anyhow::Result;
+use anyhow::{Result, bail};
use log::trace;
use std::io::Seek;
use std::{collections::BTreeMap, io::Read};
@@ -29,6 +29,8 @@ pub fn read_value(
e: Endianness,
data: &mut (impl Read + Seek),
) -> Result<Value> {
+ let mut align = false;
+ let pos_before = data.stream_position()?;
let r = match ty.type_string.as_str() {
"char" => Ok(Value::U8(data.read_u8()?)),
"int" => Ok(Value::I32(data.read_i32(e)?)),
@@ -63,10 +65,14 @@ pub fn read_value(
Ok(Value::String(String::from_utf8(bytes)?))
}
"Array" => {
+ align |= ty.children[0].post_align();
let Value::I32(size) = read_value(&ty.children[0], e, data)? else {
unreachable!()
};
trace!("array of size {size}");
+ if size > 10000 {
+ eprintln!("{ty:#?}");
+ }
let mut elems = Vec::new();
for _ in 0..size {
elems.push(read_value(&ty.children[1], e, data)?);
@@ -87,7 +93,16 @@ pub fn read_value(
})
}
};
- if ty.post_align() {
+ let pos_after = data.stream_position()?;
+ if ty.byte_size != -1 && pos_after - pos_before < ty.byte_size as u64 {
+ bail!(
+ "did not read enough data ({} expected, {} actual)",
+ ty.byte_size,
+ pos_after - pos_before
+ );
+ }
+ if align || ty.post_align() {
+ trace!("post align");
data.align(4)?;
}
r
@@ -116,7 +131,7 @@ impl Value {
.into_iter()
.map(|(k, v)| (k, v.to_json()))
.chain(Some((
- "_class".to_string(),
+ "@class".to_string(),
serde_json::Value::String(class),
)))
.collect(),
diff --git a/src/unityfs.rs b/src/unityfs.rs
index d3eb81f..0f3cab6 100644
--- a/src/unityfs.rs
+++ b/src/unityfs.rs
@@ -230,11 +230,11 @@ impl<T: Seek + Read> Seek for BlocksReader<T> {
let block_off = pos - decomp_off;
debug!("target is block={i} offset={block_off}");
- self.inner.seek(SeekFrom::Start(comp_off))?;
if self.nblock_index == i + 1 {
debug!("intra-block seek")
} else {
debug!("seek comp to {comp_off}");
+ self.inner.seek(SeekFrom::Start(comp_off))?;
self.nblock_index = i;
self.load_next_block()?;
}