diff options
-rw-r--r-- | exporter/src/bin/typegraph.rs | 97 | ||||
-rw-r--r-- | exporter/src/bin/yaml.rs | 35 | ||||
-rw-r--r-- | src/assetbundle.rs | 37 | ||||
-rw-r--r-- | src/classes/mod.rs | 2 | ||||
-rw-r--r-- | src/classes/pptr.rs | 5 | ||||
-rw-r--r-- | src/classes/vectors.rs | 2 |
6 files changed, 103 insertions, 75 deletions
diff --git a/exporter/src/bin/typegraph.rs b/exporter/src/bin/typegraph.rs index d1e7629..44e395b 100644 --- a/exporter/src/bin/typegraph.rs +++ b/exporter/src/bin/typegraph.rs @@ -18,56 +18,63 @@ 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 = SerializedFile::read(&mut cab, node.name)?; + let cab = fs.read(&node)?; + let file = SerializedFile::read(cab, node.name)?; + let mut shared = None; + if let Some(ni) = file.find_fs_shared_assets(&fs) { + let cab = fs.read(&ni)?; + shared = Some(SerializedFile::read(cab, ni.name)?); + } - for ob in file.objects { - let typetree = if ob.type_id < 0 { - unimplemented!() - } else { - &file.types[ob.type_id as usize] - }; - fn print_types( - edges: &mut BTreeSet<(String, String)>, - filter_prims: bool, - tt: TypeTreeNode, - ) { - for c in tt.children { - let mut c = vec![c]; - loop { - let mut nc = Vec::new(); - let mut f = false; - for mut c in c { - if let Some(inner) = c.type_string.strip_prefix("PPtr<") { - c.type_string = inner.strip_suffix(">").unwrap().to_owned(); - f = true; - } else if matches!( - c.type_string.as_str(), - "Array" | "pair" | "map" | "vector" - ) { - nc.extend(c.children); - f = true - } else { - nc.push(c); - }; - } - c = nc; - if !f { - break; + for file in [file].into_iter().chain(shared) { + for ob in file.objects { + let typetree = if ob.type_id < 0 { + unimplemented!() + } else { + &file.types[ob.type_id as usize] + }; + fn print_types( + edges: &mut BTreeSet<(String, String)>, + filter_prims: bool, + tt: TypeTreeNode, + ) { + for c in tt.children { + let mut c = vec![c]; + loop { + let mut nc = Vec::new(); + let mut f = false; + for mut c in c { + if let Some(inner) = c.type_string.strip_prefix("PPtr<") { + c.type_string = inner.strip_suffix(">").unwrap().to_owned(); + f = true; + nc.push(c); + } else if matches!( + c.type_string.as_str(), + "Array" | "pair" | "map" | "vector" + ) { + nc.extend(c.children); + f = true + } else { + nc.push(c); + }; + } + c = nc; + if !f { + break; + } } - } - for c in c { - if filter_prims && is_primitive(&c.type_string) { - continue; + for c in c { + if filter_prims && is_primitive(&c.type_string) { + continue; + } + edges.insert((tt.type_string.to_owned(), c.type_string.to_owned())); + print_types(edges, filter_prims, c); } - edges.insert((tt.type_string.to_owned(), c.type_string.to_owned())); - print_types(edges, filter_prims, c); } } - } - - if let Some(tree) = &typetree.type_tree { - print_types(&mut edges, filter_prims, tree.clone()); + if let Some(tree) = &typetree.type_tree { + print_types(&mut edges, filter_prims, tree.clone()); + } } } let nodes = edges diff --git a/exporter/src/bin/yaml.rs b/exporter/src/bin/yaml.rs index afa016a..a63164a 100644 --- a/exporter/src/bin/yaml.rs +++ b/exporter/src/bin/yaml.rs @@ -13,24 +13,31 @@ fn main() -> anyhow::Result<()> { let filter = args().nth(2); let node = fs.find_main_file().unwrap().to_owned(); - let mut cab = fs.read(&node)?; - let mut file = SerializedFile::read(&mut cab, node.name)?; - for ob in file.objects.clone() { - if let Some(f) = &filter { - if file.get_object_type_tree(&ob)?.type_string != *f && ob.path_id.to_string() != *f { - continue; + let cab = fs.read(&node)?; + let file = SerializedFile::read(cab, node.name)?; + let mut shared = None; + if let Some(ni) = file.find_fs_shared_assets(&fs) { + let cab = fs.read(&ni)?; + shared = Some(SerializedFile::read(cab, ni.name)?); + } + for mut file in [file].into_iter().chain(shared) { + for ob in file.objects.clone() { + if let Some(f) = &filter { + if file.get_object_type_tree(&ob)?.type_string != *f && ob.path_id.to_string() != *f + { + continue; + } } - } - let value = file.read_object(ob)?; - let hvalue = HValue::from_value(value)?; + let value = file.read_object(ob)?; + let hvalue = HValue::from_value(value)?; - let mut hvalue = serde_yml::to_value(hvalue)?; - trim_large_arrays(&mut hvalue); + let mut hvalue = serde_yml::to_value(hvalue)?; + trim_large_arrays(&mut hvalue); - serde_yml::to_writer(stdout(), &hvalue).unwrap(); - println!() + serde_yml::to_writer(stdout(), &hvalue).unwrap(); + println!() + } } - Ok(()) } diff --git a/src/assetbundle.rs b/src/assetbundle.rs index 0af9895..f87d7b8 100644 --- a/src/assetbundle.rs +++ b/src/assetbundle.rs @@ -1,16 +1,14 @@ use crate::{ classes::pptr::PPtr, serialized_file::SerializedFile, - unityfs::{ - NodeReader, UnityFS, block_reader::BlockReader, header::NodeInfo, multi_reader::MultiReader, - }, + unityfs::{UnityFS, header::NodeInfo}, }; use anyhow::{Context, Result, anyhow}; use log::debug; use std::{ collections::HashMap, fs::File, - io::{BufReader, Read, Seek}, + io::{BufReader, Cursor, Read, Seek}, marker::PhantomData, path::Path, sync::{Arc, Mutex}, @@ -19,13 +17,16 @@ use std::{ /// High-level wrapper around UnityFS, SerializedFile and all the classes. pub struct AssetBundle<T> { pub fs: UnityFS<T>, - pub ser_files: - HashMap<String, Arc<Mutex<SerializedFile<NodeReader<BlockReader<MultiReader<T>>>>>>>, + pub ser_files: HashMap<String, Arc<Mutex<SerializedFile<Box<dyn ReadSeek>>>>>, pub main_file: NodeInfo, pub default_resources: SerializedFile<BufReader<File>>, + pub full_decomp: bool, } -impl<T: Read + Seek> AssetBundle<T> { +pub trait ReadSeek: Read + Seek + 'static {} +impl<T: Read + Seek + 'static> ReadSeek for T {} + +impl<T: Read + Seek + 'static> AssetBundle<T> { pub fn open(inner: T, support_dir: impl AsRef<Path>) -> Result<Self> { let fs = UnityFS::open(inner).context("opening UnityFS")?; let main_file = fs @@ -44,21 +45,29 @@ impl<T: Read + Seek> AssetBundle<T> { fs, main_file, default_resources, + full_decomp: false, ser_files: HashMap::new(), }) } pub fn get_fs_file( &mut self, - node: &NodeInfo, - ) -> Result<Arc<Mutex<SerializedFile<NodeReader<BlockReader<MultiReader<T>>>>>>> { - if !self.ser_files.contains_key(&node.name) { - let file = - SerializedFile::read(self.fs.read(node)?, format!("archive:/{}", node.name))?; + nodeinfo: &NodeInfo, + ) -> Result<Arc<Mutex<SerializedFile<Box<dyn ReadSeek>>>>> { + if !self.ser_files.contains_key(&nodeinfo.name) { + let mut node = self.fs.read(nodeinfo)?; + let node_box = if self.full_decomp { + let mut buf = Vec::new(); + node.read_to_end(&mut buf)?; + Box::new(Cursor::new(buf)) as Box<dyn ReadSeek> + } else { + Box::new(node) as Box<dyn ReadSeek> + }; + let file = SerializedFile::read(node_box, format!("archive:/{}", nodeinfo.name))?; self.ser_files - .insert(node.name.clone(), Arc::new(Mutex::new(file))); + .insert(nodeinfo.name.clone(), Arc::new(Mutex::new(file))); } - Ok(self.ser_files.get(&node.name).unwrap().clone()) + Ok(self.ser_files.get(&nodeinfo.name).unwrap().clone()) } pub fn all_toplevel(&mut self) -> Vec<PPtr> { diff --git a/src/classes/mod.rs b/src/classes/mod.rs index bff033a..c312c6a 100644 --- a/src/classes/mod.rs +++ b/src/classes/mod.rs @@ -9,6 +9,8 @@ pub mod transform; pub mod vectors; pub mod renderer; pub mod shader; +pub mod cubemap; +pub mod render_settings; use crate::object::{Value, parser::FromValue}; use anyhow::Result; diff --git a/src/classes/pptr.rs b/src/classes/pptr.rs index 14c72b6..332d3da 100644 --- a/src/classes/pptr.rs +++ b/src/classes/pptr.rs @@ -60,7 +60,10 @@ impl<T: FromValue> PPtr<T> { pub fn is_null(&self) -> bool { self.path_id == 0 && self.file_id == 0 } - pub fn load(&self, bundle: &mut AssetBundle<impl Read + Seek>) -> Result<T> { + pub fn load(&self, bundle: &mut AssetBundle<impl Read + Seek + 'static>) -> Result<T> { + if self.is_null() { + bail!("attempted to load null PPtr") + } debug!( "loading PPtr<{}> file_id={} path_id={}", self.class, self.file_id, self.path_id diff --git a/src/classes/vectors.rs b/src/classes/vectors.rs index 14c5a59..b7127bf 100644 --- a/src/classes/vectors.rs +++ b/src/classes/vectors.rs @@ -30,7 +30,7 @@ impl FromValue for Vec4 { } } -#[derive(Debug, Serialize)] +#[derive(Debug, Serialize, Clone, Copy)] pub struct ColorRGBA(pub Vec4); impl FromValue for ColorRGBA { fn from_value(v: Value) -> anyhow::Result<Self> { |