Skip to content

Commit

Permalink
unpacker implemented + manifest path customization
Browse files Browse the repository at this point in the history
  • Loading branch information
Saegusae committed Oct 21, 2023
1 parent 5996d95 commit 7e63989
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 29 deletions.
11 changes: 7 additions & 4 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ pub enum Commands {
#[arg(long, short = 's', default_value_t = 500)]
package_size: usize,

#[arg(name = "manifest", short, long, default_value = "packed/_manifest.json")]
manifest_path: PathBuf,

#[arg(long, short, default_value = "packed")]
output_dir: PathBuf,

Expand All @@ -37,11 +40,11 @@ pub enum Commands {
#[command(arg_required_else_help = true)]
#[command(name = "unpack", about = "Unpacks client files to given directory", long_about = None)]
Unpack {
#[arg(long, short)]
input_dir: PathBuf,
#[arg(name = "manifest", short, long, default_value = "packed/_manifest.json")]
manifest_path: PathBuf,

#[arg(long, short, default_value = "manifest.json")]
manifest: PathBuf,
#[arg(long, short, default_value = "packed")]
input_dir: PathBuf,

#[arg(long, short, default_value_t = 8)]
workers: usize,
Expand Down
14 changes: 8 additions & 6 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod cli;

use cli::{Cli, Commands, Parser};
use tera_client_packer::packer::Packer;
use tera_client_packer::{packer::Packer, unpacker::Unpacker};

fn main() {
let args = Cli::parse();
Expand All @@ -11,23 +11,25 @@ fn main() {
package_name,
package_extension,
package_size,
manifest_path,
output_dir,
workers,
input_dir,
} => Packer::new(
&input_dir,
&output_dir,
&manifest_path,
package_name,
package_extension,
package_size * 1024_usize.pow(2),
workers,
)
.pack(),
Commands::Unpack {
input_dir: _,
manifest: _,
workers: _,
output_dir: _,
} => unimplemented!(),
manifest_path,
input_dir,
output_dir,
workers,
} => Unpacker::new(&manifest_path, &input_dir, &output_dir, workers).unpack(),
}
}
31 changes: 20 additions & 11 deletions src/packer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,24 @@ pub struct Packer<'a> {
package_ext: String,
package_size: usize,

manifest_path: &'a Path,
input_dir: &'a Path,
output_dir: &'a Path,
}

impl<'a> Default for Packer<'a> {
fn default() -> Self {
Self {
input_dir: Path::new("."),
output_dir: Path::new("packed"),
worker_count: 0,
workers: ThreadPoolBuilder::new().build().unwrap(),

package_name: String::from("client"),
package_ext: String::from("cabx"),
package_size: 500 * 1024_usize.pow(2),
worker_count: 0,
workers: ThreadPoolBuilder::new().build().unwrap(),

manifest_path: Path::new("packed/_manifest.json"),
input_dir: Path::new("."),
output_dir: Path::new("packed"),
}
}
}
Expand All @@ -46,19 +50,23 @@ impl<'a> Packer<'a> {
pub fn new(
input_dir: &'a Path,
output_dir: &'a Path,
manifest_path: &'a Path,
package_name: String,
package_ext: String,
package_size: usize,
worker_count: usize,
) -> Self {
Self {
input_dir,
output_dir,
worker_count,
workers: ThreadPoolBuilder::new().num_threads(worker_count).build().unwrap(),

package_name,
package_ext,
package_size,
worker_count,
workers: ThreadPoolBuilder::new().num_threads(worker_count).build().unwrap(),

manifest_path,
input_dir,
output_dir,
}
}

Expand All @@ -69,6 +77,7 @@ impl<'a> Packer<'a> {
let package_size = self.package_size;

let (package_name, package_ext) = (self.package_name.clone(), self.package_ext.clone());
let manifest_path = self.manifest_path.to_owned();

let manager = thread::spawn(move || {
let mut sources = WalkDir::new(&source_input)
Expand Down Expand Up @@ -150,7 +159,7 @@ impl<'a> Packer<'a> {
}
}

manifest.set_total_size(total_size).write("./_manifest.json");
manifest.set_total_size(total_size).write(manifest_path);
});

self.workers.broadcast(|_| {
Expand All @@ -167,10 +176,10 @@ impl<'a> Packer<'a> {
let mut tee = TeeReader::new(encoder, &mut hasher);
let mut file = File::create(output_path).unwrap();

let bytes = io::copy(&mut tee, &mut file).unwrap();
let _bytes = io::copy(&mut tee, &mut file).unwrap();
let hash = hasher.finalize();

println!("Package {}: {:?}", idx, hash);
println!("Package {}: {:x}", idx, hash);
}
});

Expand Down
48 changes: 40 additions & 8 deletions src/unpacker/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,33 +6,48 @@ use crossbeam::channel;
use flate2::read::GzDecoder;
use rayon::{ThreadPool, ThreadPoolBuilder};

use std::{fs::File, thread};
use std::fs::{self, File};
use std::io::{self, Read};
use std::path::Path;
use std::thread;

pub struct Unpacker {
pub struct Unpacker<'a> {
worker_count: usize,
workers: ThreadPool,

manifest_path: &'a Path,
input_dir: &'a Path,
output_dir: &'a Path,
}

impl Default for Unpacker {
impl<'a> Default for Unpacker<'a> {
fn default() -> Self {
Self {
worker_count: 0,
workers: ThreadPoolBuilder::new().build().unwrap(),

manifest_path: Path::new("packed/_manifest.json"),
input_dir: Path::new("packed"),
output_dir: Path::new("unpacked"),
}
}
}

impl Unpacker {
pub fn new(worker_count: usize) -> Self {
impl<'a> Unpacker<'a> {
pub fn new(manifest_path: &'a Path, input_dir: &'a Path, output_dir: &'a Path, worker_count: usize) -> Self {
Self {
worker_count,
workers: ThreadPoolBuilder::new().num_threads(worker_count).build().unwrap(),

manifest_path,
input_dir,
output_dir,
}
}

pub fn unpack(&self) {
let (tx, rx) = channel::bounded::<PackageEntry>(self.worker_count);
let manifest = Manifest::from_file("./_manifest.json");
let manifest = Manifest::from_file(self.manifest_path);

let manager = thread::spawn(move || {
for package in manifest.package_list {
Expand All @@ -41,8 +56,25 @@ impl Unpacker {
});

self.workers.broadcast(|_| {
while let Ok(_package) = rx.recv() {
let source = File::open(_package.name).unwrap();
while let Ok(package) = rx.recv() {
let file_path = self.input_dir.join(package.name);
let file = File::open(file_path).unwrap();

let mut decoder = GzDecoder::new(file);
for entry in package.file_list {
let mut buffer = vec![0u8; entry.size as usize];
decoder.read_exact(&mut buffer).unwrap();

let client_file_path = self.output_dir.join(entry.key);
let parent_dir = client_file_path.parent().unwrap();

if !parent_dir.exists() {
fs::create_dir_all(parent_dir).unwrap()
}
let mut output_file = File::create(client_file_path).unwrap();

io::copy(&mut buffer.as_slice(), &mut output_file).unwrap();
}
}
});

Expand Down

0 comments on commit 7e63989

Please sign in to comment.