cs2-dumper/src/main.rs

139 lines
3.8 KiB
Rust
Raw Normal View History

use std::env;
2024-03-28 20:19:20 +08:00
use std::path::PathBuf;
2024-03-01 23:02:58 +08:00
use std::time::Instant;
2023-10-20 13:23:43 +08:00
2024-03-28 20:19:20 +08:00
use clap::*;
2023-10-26 13:41:34 +08:00
2024-03-28 20:19:20 +08:00
use log::{info, Level};
2023-09-28 22:41:21 +08:00
2024-03-28 20:19:20 +08:00
use memflow::prelude::v1::*;
2023-10-26 13:41:34 +08:00
2024-03-28 20:19:20 +08:00
use simplelog::{ColorChoice, TermLogger};
2023-10-26 13:41:34 +08:00
2024-03-28 20:19:20 +08:00
use error::Result;
use output::Results;
2023-09-25 22:46:10 +08:00
2024-03-28 20:19:20 +08:00
mod analysis;
mod error;
2024-04-06 01:20:08 +08:00
mod mem;
2024-03-28 20:19:20 +08:00
mod output;
mod source2;
const PROCESS_NAME: &str = "cs2.exe";
2023-09-28 22:41:21 +08:00
2023-09-25 22:46:10 +08:00
fn main() -> Result<()> {
2024-03-28 20:19:20 +08:00
let start_time = Instant::now();
let matches = parse_args();
2024-04-01 17:09:44 +08:00
let (conn_name, conn_args, indent_size, out_dir) = extract_args(&matches)?;
2024-03-28 20:19:20 +08:00
let os = if let Some(conn_name) = conn_name {
let inventory = Inventory::scan();
inventory
.builder()
.connector(&conn_name)
.args(conn_args)
2024-04-01 17:09:44 +08:00
.os("win32")
2024-03-28 20:19:20 +08:00
.build()?
2023-10-01 12:43:48 +08:00
} else {
2024-03-28 20:19:20 +08:00
// Fallback to the native OS layer if no connector name was provided.
memflow_native::create_os(&Default::default(), Default::default())?
2023-10-01 12:43:48 +08:00
};
2023-09-28 22:41:21 +08:00
let mut process = os.into_process_by_name(PROCESS_NAME)?;
2023-10-26 13:41:34 +08:00
2024-03-28 20:19:20 +08:00
let buttons = analysis::buttons(&mut process)?;
let interfaces = analysis::interfaces(&mut process)?;
let offsets = analysis::offsets(&mut process)?;
let schemas = analysis::schemas(&mut process)?;
2023-10-01 12:43:48 +08:00
2024-03-28 20:19:20 +08:00
let results = Results::new(buttons, interfaces, offsets, schemas);
2023-09-25 22:46:10 +08:00
results.dump_all(&mut process, &out_dir, indent_size)?;
2024-03-28 20:19:20 +08:00
info!("finished in {:?}", start_time.elapsed());
2023-09-25 22:46:10 +08:00
2024-03-28 20:19:20 +08:00
Ok(())
}
2023-10-26 13:41:34 +08:00
2024-03-28 20:19:20 +08:00
fn parse_args() -> ArgMatches {
Command::new("cs2-dumper")
.version(crate_version!())
.author(crate_authors!())
.arg(
Arg::new("verbose")
.help("Increase logging verbosity. Can be specified multiple times.")
.short('v')
.action(ArgAction::Count),
)
.arg(
Arg::new("connector")
.help("The name of the memflow connector to use.")
.long("connector")
.short('c')
.required(false),
)
.arg(
Arg::new("connector-args")
.help("Additional arguments to supply to the connector.")
.long("connector-args")
.short('a')
.required(false),
)
.arg(
Arg::new("output")
.help("The output directory to write the generated files to.")
.long("output")
.short('o')
2024-03-28 20:19:20 +08:00
.default_value("output")
.value_parser(value_parser!(PathBuf))
.required(false),
)
.arg(
Arg::new("indent-size")
.help("The number of spaces to use per indentation level.")
.long("indent-size")
.short('i')
.default_value("4")
.value_parser(value_parser!(usize))
.required(false),
)
.get_matches()
}
2024-04-01 17:09:44 +08:00
fn extract_args(matches: &ArgMatches) -> Result<(Option<String>, ConnectorArgs, usize, &PathBuf)> {
2024-03-28 20:19:20 +08:00
use std::str::FromStr;
2023-09-28 22:41:21 +08:00
2024-03-28 20:19:20 +08:00
let log_level = match matches.get_count("verbose") {
0 => Level::Error,
1 => Level::Warn,
2 => Level::Info,
3 => Level::Debug,
4 => Level::Trace,
_ => Level::Trace,
};
2023-09-28 22:41:21 +08:00
2024-03-28 20:19:20 +08:00
TermLogger::init(
log_level.to_level_filter(),
Default::default(),
Default::default(),
ColorChoice::Auto,
)
.unwrap();
2023-09-25 22:46:10 +08:00
2024-03-28 20:19:20 +08:00
let conn_name = matches
.get_one::<String>("connector")
.map(|s| s.to_string());
2023-09-25 22:46:10 +08:00
2024-03-28 20:19:20 +08:00
let conn_args = matches
.get_one::<String>("connector-args")
.map(|s| ConnectorArgs::from_str(&s).expect("unable to parse connector arguments"))
.unwrap_or_default();
2023-09-25 22:46:10 +08:00
2024-03-28 20:19:20 +08:00
let indent_size = *matches.get_one::<usize>("indent-size").unwrap();
let out_dir = matches.get_one::<PathBuf>("output").unwrap();
2024-04-01 17:09:44 +08:00
Ok((conn_name, conn_args, indent_size, out_dir))
}