1
Fork 0
mirror of https://github.com/redstrate/Physis.git synced 2025-04-20 11:47:46 +00:00
physis/examples/extractor.rs
Joshua Goins d58a216462 Shrink the dependency and feature complexity, auto-cleanup and more
We had a few odd dependencies that caused nothing but pain in dependent projects
like libphysis. One of these was libunshield (a C library) that our game_install
feature used, but to be honest this was the wrong library to put this code. It
was really only ever used by Astra, and should live there instead - there's no
reason to have it shared between applications (and it's small enough to be
copied if *you* need it.) Also that also killed the system-deps dependency which
had a significant impact on our build time.

Another dependency was replaced: libz-sys. This is replaced by the pure Rust
libz-rs (through libz-rs-sys) which should simplify deploying physis without
having to worry about manually linking libz or other nonsense. Some leftover
copied code from flate2 can also be removed.

I also removed the visual_data feature as Astra ended up using it anyway, and
the distinction doesn't make much sense now. It was previously to gate some
dependencies needed for visual data extraction, but the bitflags and half crates
are small. I can look into splitting the crate up into more features if needed
later.

A dependency that was erroneously included in the refactoring was quote, which
has been removed. Also ran cargo fmt, clippy too.
2025-03-11 16:29:24 -04:00

51 lines
1.6 KiB
Rust

// SPDX-FileCopyrightText: 2024 Joshua Goins <josh@redstrate.com>
// SPDX-License-Identifier: GPL-3.0-or-later
use physis::common::Platform;
use physis::gamedata::GameData;
use std::env;
use std::fs::File;
use std::io::Write;
/// A simple program that allows a user to extract raw files from the game
fn main() {
let args: Vec<String> = env::args().collect();
if args.len() != 4 {
println!("Usage: extractor [game dir] [filepath_to_extract] [destination]");
return;
}
/// Collect our arguments
let game_dir = &args[1];
let file_path = &args[2];
let destination_path = &args[3];
/// Create a GameData struct, this manages the repositories. It allows us to easily extract files.
let Some(mut game_data) = GameData::from_existing(Platform::Win32, game_dir) else {
println!("Invalid game directory ({})!", game_dir);
return;
};
/// Extract said file:
let Some(game_file) = game_data.extract(file_path) else {
println!("File {} not found!", file_path);
return;
};
/// Create the file to write into.
let Ok(mut file) = File::create(destination_path) else {
println!("Failed to open file {} for writing.", destination_path);
return;
};
/// Since GameData::extract returns a byte buffer, it's trivial to write that to a file on disk.
if file.write_all(&game_file).is_err() {
println!("Failed to write to file {}.", destination_path);
return;
};
println!(
"Successfully extracted {} to {}!",
file_path, destination_path
);
}