use crate::{ object::{Value, parser::FromValue}, unityfs::UnityFS, }; use anyhow::{Result, anyhow, bail}; use serde::Serialize; use std::io::{Read, Seek, SeekFrom}; #[derive(Debug, Serialize)] pub struct StreamedResource { pub offset: u64, pub size: u64, pub path: String, } impl FromValue for StreamedResource { fn from_value(v: Value) -> Result { let mut fields = v.as_class("StreamedResource")?; Ok(StreamedResource { offset: fields.field("m_Offset")?, size: fields.field("m_Size")?, path: fields.field("m_Source")?, }) } } impl StreamedResource { pub fn read(&self, fs: &UnityFS) -> Result> { if !self.path.starts_with("archive:") { bail!( "StreamedResource path does not start on 'archive:' ({:?})", self.path ) } let nodeinfo = fs .header .nodes() .iter() .find(|n| self.path.ends_with(&n.name)) .ok_or(anyhow!("node with path {:?} not found", self.path))? .to_owned(); let mut buf = Vec::new(); let mut node = fs.read(&nodeinfo)?; node.seek(SeekFrom::Start(self.offset))?; node.take(self.size).read_to_end(&mut buf)?; Ok(buf) } }