Обновление структуры проекта
This commit is contained in:
		
							
								
								
									
										14
									
								
								tools/nres-cli/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								tools/nres-cli/Cargo.toml
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
			
		||||
[package]
 | 
			
		||||
name = "nres-cli"
 | 
			
		||||
version = "0.2.3"
 | 
			
		||||
edition = "2021"
 | 
			
		||||
 | 
			
		||||
[dependencies]
 | 
			
		||||
byteorder = "1.4"
 | 
			
		||||
clap = { version = "4.2", features = ["derive"] }
 | 
			
		||||
console = "0.15"
 | 
			
		||||
dialoguer = { version = "0.11", features = ["completion"] }
 | 
			
		||||
indicatif = "0.17"
 | 
			
		||||
libnres = { version = "0.1", path = "../../libs/nres" }
 | 
			
		||||
miette = { version = "7.0", features = ["fancy"] }
 | 
			
		||||
tempdir = "0.3"
 | 
			
		||||
							
								
								
									
										6
									
								
								tools/nres-cli/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tools/nres-cli/README.md
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
			
		||||
# Console tool for NRes files (Deprecated)
 | 
			
		||||
 | 
			
		||||
## Commands
 | 
			
		||||
 | 
			
		||||
- `extract` - Extract game resources from a "NRes" file.
 | 
			
		||||
- `ls` - Get a list of files in a "NRes" file.
 | 
			
		||||
							
								
								
									
										198
									
								
								tools/nres-cli/src/main.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										198
									
								
								tools/nres-cli/src/main.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,198 @@
 | 
			
		||||
extern crate core;
 | 
			
		||||
extern crate libnres;
 | 
			
		||||
 | 
			
		||||
use std::io::Write;
 | 
			
		||||
 | 
			
		||||
use clap::{Parser, Subcommand};
 | 
			
		||||
use miette::{IntoDiagnostic, Result};
 | 
			
		||||
 | 
			
		||||
#[derive(Parser, Debug)]
 | 
			
		||||
#[command(name = "NRes CLI")]
 | 
			
		||||
#[command(about, author, version, long_about = None)]
 | 
			
		||||
struct Cli {
 | 
			
		||||
    #[command(subcommand)]
 | 
			
		||||
    command: Commands,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#[derive(Subcommand, Debug)]
 | 
			
		||||
enum Commands {
 | 
			
		||||
    /// Check if the "NRes" file can be extract
 | 
			
		||||
    Check {
 | 
			
		||||
        /// "NRes" file
 | 
			
		||||
        file: String,
 | 
			
		||||
    },
 | 
			
		||||
    /// Print debugging information on the "NRes" file
 | 
			
		||||
    #[command(arg_required_else_help = true)]
 | 
			
		||||
    Debug {
 | 
			
		||||
        /// "NRes" file
 | 
			
		||||
        file: String,
 | 
			
		||||
        /// Filter results by file name
 | 
			
		||||
        #[arg(long)]
 | 
			
		||||
        name: Option<String>,
 | 
			
		||||
    },
 | 
			
		||||
    /// Extract files or a file from the "NRes" file
 | 
			
		||||
    #[command(arg_required_else_help = true)]
 | 
			
		||||
    Extract {
 | 
			
		||||
        /// "NRes" file
 | 
			
		||||
        file: String,
 | 
			
		||||
        /// Overwrite files
 | 
			
		||||
        #[arg(short, long, default_value_t = false, value_name = "TRUE|FALSE")]
 | 
			
		||||
        force: bool,
 | 
			
		||||
        /// Outbound directory
 | 
			
		||||
        #[arg(short, long, value_name = "DIR")]
 | 
			
		||||
        out: String,
 | 
			
		||||
    },
 | 
			
		||||
    /// Print a list of files in the "NRes" file
 | 
			
		||||
    #[command(arg_required_else_help = true)]
 | 
			
		||||
    Ls {
 | 
			
		||||
        /// "NRes" file
 | 
			
		||||
        file: String,
 | 
			
		||||
    },
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
pub fn main() -> Result<()> {
 | 
			
		||||
    let stdout = console::Term::stdout();
 | 
			
		||||
    let cli = Cli::parse();
 | 
			
		||||
 | 
			
		||||
    match cli.command {
 | 
			
		||||
        Commands::Check { file } => command_check(stdout, file)?,
 | 
			
		||||
        Commands::Debug { file, name } => command_debug(stdout, file, name)?,
 | 
			
		||||
        Commands::Extract { file, force, out } => command_extract(stdout, file, out, force)?,
 | 
			
		||||
        Commands::Ls { file } => command_ls(stdout, file)?,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn command_check(_stdout: console::Term, file: String) -> Result<()> {
 | 
			
		||||
    let file = std::fs::File::open(file).into_diagnostic()?;
 | 
			
		||||
    let list = libnres::reader::get_list(&file).into_diagnostic()?;
 | 
			
		||||
    let tmp = tempdir::TempDir::new("nres").into_diagnostic()?;
 | 
			
		||||
    let bar = indicatif::ProgressBar::new(list.len() as u64);
 | 
			
		||||
 | 
			
		||||
    bar.set_style(get_bar_style()?);
 | 
			
		||||
 | 
			
		||||
    for element in list {
 | 
			
		||||
        bar.set_message(element.get_filename());
 | 
			
		||||
 | 
			
		||||
        let path = tmp.path().join(element.get_filename());
 | 
			
		||||
        let mut output = std::fs::File::create(path).into_diagnostic()?;
 | 
			
		||||
        let mut buffer = libnres::reader::get_file(&file, &element).into_diagnostic()?;
 | 
			
		||||
 | 
			
		||||
        output.write_all(&buffer).into_diagnostic()?;
 | 
			
		||||
        buffer.clear();
 | 
			
		||||
        bar.inc(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bar.finish();
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn command_debug(stdout: console::Term, file: String, name: Option<String>) -> Result<()> {
 | 
			
		||||
    let file = std::fs::File::open(file).into_diagnostic()?;
 | 
			
		||||
    let mut list = libnres::reader::get_list(&file).into_diagnostic()?;
 | 
			
		||||
 | 
			
		||||
    let mut total_files_size: u32 = 0;
 | 
			
		||||
    let mut total_files_gap: u32 = 0;
 | 
			
		||||
    let mut total_files: u32 = 0;
 | 
			
		||||
 | 
			
		||||
    for (index, item) in list.iter().enumerate() {
 | 
			
		||||
        total_files_size += item.size;
 | 
			
		||||
        total_files += 1;
 | 
			
		||||
        let mut gap = 0;
 | 
			
		||||
 | 
			
		||||
        if index > 1 {
 | 
			
		||||
            let previous_item = &list[index - 1];
 | 
			
		||||
            gap = item.position - (previous_item.position + previous_item.size);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        total_files_gap += gap;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if let Some(name) = name {
 | 
			
		||||
        list.retain(|item| item.name.contains(&name));
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    for (index, item) in list.iter().enumerate() {
 | 
			
		||||
        let mut gap = 0;
 | 
			
		||||
 | 
			
		||||
        if index > 1 {
 | 
			
		||||
            let previous_item = &list[index - 1];
 | 
			
		||||
            gap = item.position - (previous_item.position + previous_item.size);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let text = format!("Index: {};\nGap: {};\nItem: {:#?};\n", index, gap, item);
 | 
			
		||||
        stdout.write_line(&text).into_diagnostic()?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let text = format!(
 | 
			
		||||
        "Total files: {};\nTotal files gap: {} (bytes);\nTotal files size: {} (bytes);",
 | 
			
		||||
        total_files, total_files_gap, total_files_size
 | 
			
		||||
    );
 | 
			
		||||
 | 
			
		||||
    stdout.write_line(&text).into_diagnostic()?;
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn command_extract(_stdout: console::Term, file: String, out: String, force: bool) -> Result<()> {
 | 
			
		||||
    let file = std::fs::File::open(file).into_diagnostic()?;
 | 
			
		||||
    let list = libnres::reader::get_list(&file).into_diagnostic()?;
 | 
			
		||||
    let bar = indicatif::ProgressBar::new(list.len() as u64);
 | 
			
		||||
 | 
			
		||||
    bar.set_style(get_bar_style()?);
 | 
			
		||||
 | 
			
		||||
    for element in list {
 | 
			
		||||
        bar.set_message(element.get_filename());
 | 
			
		||||
 | 
			
		||||
        let path = format!("{}/{}", out, element.get_filename());
 | 
			
		||||
 | 
			
		||||
        if !force && is_exist_file(&path) {
 | 
			
		||||
            let message = format!("File \"{}\" exists. Overwrite it?", path);
 | 
			
		||||
 | 
			
		||||
            if !dialoguer::Confirm::new()
 | 
			
		||||
                .with_prompt(message)
 | 
			
		||||
                .interact()
 | 
			
		||||
                .into_diagnostic()?
 | 
			
		||||
            {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        let mut output = std::fs::File::create(path).into_diagnostic()?;
 | 
			
		||||
        let mut buffer = libnres::reader::get_file(&file, &element).into_diagnostic()?;
 | 
			
		||||
 | 
			
		||||
        output.write_all(&buffer).into_diagnostic()?;
 | 
			
		||||
        buffer.clear();
 | 
			
		||||
        bar.inc(1);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bar.finish();
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn command_ls(stdout: console::Term, file: String) -> Result<()> {
 | 
			
		||||
    let file = std::fs::File::open(file).into_diagnostic()?;
 | 
			
		||||
    let list = libnres::reader::get_list(&file).into_diagnostic()?;
 | 
			
		||||
 | 
			
		||||
    for element in list {
 | 
			
		||||
        stdout.write_line(&element.name).into_diagnostic()?;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Ok(())
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn get_bar_style() -> Result<indicatif::ProgressStyle> {
 | 
			
		||||
    Ok(
 | 
			
		||||
        indicatif::ProgressStyle::with_template("[{bar:32}] {pos:>7}/{len:7} {msg}")
 | 
			
		||||
            .into_diagnostic()?
 | 
			
		||||
            .progress_chars("=>-"),
 | 
			
		||||
    )
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn is_exist_file(path: &String) -> bool {
 | 
			
		||||
    let metadata = std::path::Path::new(path);
 | 
			
		||||
    metadata.exists()
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user