Add Asset structure

This commit is contained in:
Piotr Siuszko 2023-12-27 23:30:14 +01:00
parent 25fa59820f
commit a9426fc3b9
3 changed files with 79 additions and 46 deletions

65
src/asset.rs Normal file
View File

@ -0,0 +1,65 @@
use std::ffi::OsStr;
use std::fs;
use std::fs::DirEntry;
use std::fs::File;
use std::io::BufRead;
use std::io::BufReader;
use std::path::{Path, PathBuf};
#[derive(Clone)]
pub struct Asset {
pub extension: Option<String>,
pub hash: String,
pub path_name: String,
pub has_meta: bool,
}
impl Asset {
pub fn from_path(entry: &DirEntry) -> Option<Asset> {
let root_file = entry.path();
if !root_file.is_dir() {
return None;
}
let asset = entry.file_name().into_string().unwrap();
let mut real_path = String::new();
let mut extension = None;
let mut has_asset = false;
let mut has_meta = false;
for sub_entry in fs::read_dir(root_file.clone()).unwrap() {
let sub_entry = sub_entry.unwrap();
let file_name = sub_entry.file_name().into_string().unwrap();
match file_name.as_str() {
"pathname" => {
let path = sub_entry.path();
let file = File::open(path).unwrap();
let buf_reader = BufReader::new(file);
let line = buf_reader.lines().next();
match line {
Some(Ok(path)) => {
real_path = path;
if let Some(e) =
Path::new(&real_path).extension().and_then(OsStr::to_str)
{
extension = Some(String::from(e));
}
}
_ => continue,
}
}
"asset" => has_asset = true,
"asset.meta" => has_meta = true,
_ => continue,
}
}
if has_asset {
Some(Asset {
extension,
hash: asset,
path_name: real_path,
has_meta,
})
} else {
None
}
}
}

View File

@ -1,15 +1,9 @@
mod args; mod args;
pub mod asset;
mod unpacker; mod unpacker;
use clap::Parser; use clap::Parser;
fn main() { fn main() {
let args = crate::args::Args::parse(); let args = crate::args::Args::parse();
let unpacker = crate::unpacker::Unpacker { args }; let unpacker = crate::unpacker::Unpacker { args };

View File

@ -1,16 +1,16 @@
use crate::asset::Asset;
use flate2::read::GzDecoder; use flate2::read::GzDecoder;
use hashbrown::HashMap; use hashbrown::HashMap;
use rayon::prelude::*;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs::File; use std::fs::File;
use std::io::BufRead; use std::io::BufRead;
use std::io::BufReader; use std::io::BufReader;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
use std::sync::mpsc::channel;
use std::sync::Arc; use std::sync::Arc;
use std::{fs, io}; use std::{fs, io};
use rayon::prelude::*;
use std::sync::mpsc::channel;
use tar::Archive; use tar::Archive;
#[derive(Clone)] #[derive(Clone)]
@ -52,54 +52,28 @@ impl Unpacker {
.par_bridge() .par_bridge()
.for_each_with(sender, |s, entry| { .for_each_with(sender, |s, entry| {
let entry = entry.unwrap(); let entry = entry.unwrap();
let root_file = entry.path(); let asset = crate::asset::Asset::from_path(&entry);
let asset = entry.file_name().into_string().unwrap(); if let Some(asset) = asset {
if !root_file.is_dir() { let extension = &asset.extension.clone().unwrap_or_default();
return; if !ignored_extensions.contains(extension) {
s.send(asset).unwrap();
} }
let mut real_path = String::new();
let mut extension = None;
let mut has_asset = false;
for sub_entry in fs::read_dir(root_file.clone()).unwrap() {
let sub_entry = sub_entry.unwrap();
let file_name = sub_entry.file_name().into_string().unwrap();
if file_name == "pathname" {
let path = sub_entry.path();
let file = File::open(path).unwrap();
let buf_reader = BufReader::new(file);
let line = buf_reader.lines().next();
match line {
Some(Ok(path)) => {
real_path = path;
if let Some(e) =
Path::new(&real_path).extension().and_then(OsStr::to_str)
{
extension = Some(String::from(e));
}
}
_ => continue,
}
} else if file_name == "asset" {
has_asset = true;
}
}
if has_asset && !ignored_extensions.contains(&extension.unwrap_or_default()) {
s.send((asset, real_path)).unwrap();
} }
}); });
let tmp_dir = Arc::new(tmp_path); let tmp_dir = Arc::new(tmp_path);
fs::create_dir(output_dir).unwrap(); fs::create_dir(output_dir).unwrap();
let output_dir = Arc::new(output_dir); let output_dir = Arc::new(output_dir);
let mapping: HashMap<String, String> = receiver.iter().collect(); let mapping: Vec<Asset> = receiver.iter().collect();
let mapping_arc = Arc::new(mapping); let mapping_arc = Arc::new(mapping);
mapping_arc.par_iter().for_each(|(asset_hash, asset_path)| { mapping_arc.par_iter().for_each(|(asset)| {
let path = Path::new(asset_path); let asset_hash = &asset.hash;
let path = Path::new(&asset.path_name);
let source_asset = Path::new(&*tmp_dir).join(asset_hash).join("asset"); let source_asset = Path::new(&*tmp_dir).join(asset_hash).join("asset");
let result_path = output_dir.join(path); let result_path = output_dir.join(path);
process_directory(asset_hash, asset_path, &result_path); process_directory(asset_hash, &asset.path_name, &result_path);
check_source_asset_exists(&source_asset); check_source_asset_exists(&source_asset);
if self.args.fbx_to_gltf.is_some() { if self.args.fbx_to_gltf.is_some() {