cs2-dumper/src/main.rs

143 lines
3.5 KiB
Rust
Raw Normal View History

2023-09-25 22:46:10 +08:00
#![allow(dead_code)]
2023-10-15 20:17:02 +08:00
#![feature(offset_of)]
2023-09-25 22:46:10 +08:00
2023-10-20 13:23:43 +08:00
use anyhow::Result;
2023-10-26 13:41:34 +08:00
use builder::*;
2023-09-28 22:41:21 +08:00
use clap::Parser;
2023-10-26 13:41:34 +08:00
use dumper::{dump_interfaces, dump_offsets, dump_schemas};
2023-09-25 22:46:10 +08:00
2023-10-26 13:41:34 +08:00
use log::LevelFilter;
use simplelog::{info, ColorChoice, ConfigBuilder, TermLogger, TerminalMode};
use std::fs;
use std::time::Instant;
use util::Process;
2023-09-25 22:46:10 +08:00
mod builder;
mod config;
2023-10-26 13:41:34 +08:00
mod dumper;
2023-09-25 22:46:10 +08:00
mod sdk;
2023-10-26 13:41:34 +08:00
mod util;
2023-09-25 22:46:10 +08:00
2023-10-26 13:41:34 +08:00
/// Command line arguments for the program.
2023-10-01 20:51:44 +08:00
#[derive(Debug, Parser)]
2023-10-26 13:41:34 +08:00
#[command(name = "cs2-dumper")]
#[command(author = "a2x")]
#[command(version = "1.1.5")]
2023-09-28 22:41:21 +08:00
struct Args {
2023-10-26 13:41:34 +08:00
/// Dump interfaces.
2023-09-28 22:41:21 +08:00
#[arg(short, long)]
interfaces: bool,
2023-10-26 13:41:34 +08:00
/// Dump offsets.
2023-09-28 22:41:21 +08:00
#[arg(short, long)]
offsets: bool,
2023-10-26 14:40:24 +08:00
/// Dump schema system classes.
2023-09-28 22:41:21 +08:00
#[arg(short, long)]
schemas: bool,
2023-10-01 12:43:48 +08:00
/// List of file builders to use.
/// Valid values are: `.cs`, `.hpp`, `.json`, `.py`, `.rs`, `.yaml`.
#[arg(
short,
long,
value_parser = parse_extension,
value_delimiter = ',',
default_values = [".cs", ".hpp", ".json", ".py", ".rs", ".yaml"],
)]
builders: Vec<FileBuilderEnum>,
/// Indentation level for generated files.
/// Defaults to 4 spaces.
#[arg(long, default_value_t = 4)]
indent: usize,
2023-10-26 13:41:34 +08:00
/// Output directory for generated files.
/// Defaults to `generated`.
2023-10-26 14:40:24 +08:00
#[arg(long, default_value = "generated")]
2023-10-26 13:41:34 +08:00
output: String,
/// Enable verbose output.
#[arg(short, long)]
verbose: bool,
2023-09-28 22:41:21 +08:00
}
2023-09-25 22:46:10 +08:00
fn main() -> Result<()> {
2023-09-28 22:41:21 +08:00
let Args {
interfaces,
offsets,
schemas,
mut builders,
2023-10-26 13:41:34 +08:00
indent,
output,
verbose,
2023-09-28 22:41:21 +08:00
} = Args::parse();
2023-10-01 12:43:48 +08:00
let log_level = if verbose {
2023-10-26 13:41:34 +08:00
LevelFilter::Debug
2023-10-01 12:43:48 +08:00
} else {
2023-10-26 13:41:34 +08:00
LevelFilter::Info
2023-10-01 12:43:48 +08:00
};
2023-09-28 22:41:21 +08:00
2023-10-26 13:41:34 +08:00
let config = ConfigBuilder::new().add_filter_ignore_str("goblin").build();
TermLogger::init(log_level, config, TerminalMode::Mixed, ColorChoice::Auto)?;
2023-10-01 12:43:48 +08:00
2023-10-26 13:41:34 +08:00
let now = Instant::now();
2023-09-25 22:46:10 +08:00
2023-10-26 13:41:34 +08:00
fs::create_dir_all(&output)?;
2023-09-25 22:46:10 +08:00
2023-10-26 13:41:34 +08:00
let mut process = Process::new("cs2.exe")?;
process.initialize()?;
2023-10-01 12:43:48 +08:00
2023-10-05 17:24:14 +08:00
let all = !(interfaces || offsets || schemas);
2023-09-28 22:41:21 +08:00
if schemas || all {
2023-10-26 13:41:34 +08:00
dump_schemas(&mut process, &mut builders, &output, indent)?;
2023-09-28 22:41:21 +08:00
}
if interfaces || all {
2023-10-26 13:41:34 +08:00
dump_interfaces(&mut process, &mut builders, &output, indent)?;
2023-09-28 22:41:21 +08:00
}
2023-09-25 22:46:10 +08:00
2023-09-28 22:41:21 +08:00
if offsets || all {
2023-10-26 13:41:34 +08:00
dump_offsets(&mut process, &mut builders, &output, indent)?;
2023-09-28 22:41:21 +08:00
}
2023-09-25 22:46:10 +08:00
2023-10-26 13:41:34 +08:00
info!(
"<on-green>Done!</> <green>Time elapsed: <b>{:?}</></>",
2023-10-26 13:41:34 +08:00
now.elapsed()
);
2023-09-25 22:46:10 +08:00
Ok(())
}
/// Parses the given file extension and returns the corresponding `FileBuilderEnum`.
///
/// # Arguments
///
/// * `extension` - A string slice that represents the file extension.
///
/// # Returns
///
/// * `Ok(FileBuilderEnum)` - If the extension is valid, returns the corresponding `FileBuilderEnum`.
/// * `Err(&'static str)` - If the extension is invalid, returns an error message.
fn parse_extension(extension: &str) -> Result<FileBuilderEnum, &'static str> {
match extension {
".cs" => Ok(FileBuilderEnum::CSharpFileBuilder(CSharpFileBuilder)),
".hpp" => Ok(FileBuilderEnum::CppFileBuilder(CppFileBuilder)),
".json" => Ok(FileBuilderEnum::JsonFileBuilder(JsonFileBuilder::default())),
".py" => Ok(FileBuilderEnum::PythonFileBuilder(PythonFileBuilder)),
".rs" => Ok(FileBuilderEnum::RustFileBuilder(RustFileBuilder)),
".yaml" => Ok(FileBuilderEnum::YamlFileBuilder(YamlFileBuilder)),
_ => Err("Invalid file extension"),
}
}