Compare commits

...

3 Commits

Author SHA1 Message Date
a2x
86dc0fa8f6 Refactor config file handling 2024-04-01 20:39:08 +10:00
a2x
ef5ff1c5f4 Update argument name for output directory 2024-04-01 19:13:13 +10:00
a2x
4a10ad3ba6 Remove unused OS name argument 2024-04-01 19:09:44 +10:00
3 changed files with 34 additions and 41 deletions

View File

@ -19,20 +19,16 @@ toolchain must be installed.
- For Linux: `config_linux.json` - For Linux: `config_linux.json`
- For Windows: `config_win.json` - For Windows: `config_win.json`
When running the executable without providing an optional memflow connector name, it will default to using the When running the executable without providing an optional memflow connector name, it will default to using the [memflow-native](https://github.com/memflow/memflow-native) cross-platform OS layer to read the memory of the game process. If you wish to use an existing memflow connector instead, pass the `connector` and optional `connector-args` arguments to the program.
memflow-native cross-platform OS layer to read the game's memory. However, any existing memflow connectors should work
out of the box.
Just pass the `connector` and optional `connector-args` arguments to the program.
E.g. `cs2-dumper.exe -c pcileech -a device=fpga -vvv` E.g. `./cs2-dumper -c kvm -vvv`
### Available Arguments ### Available Arguments
- `-v...`: Increase logging verbosity. Can be specified multiple times. - `-v...`: Increase logging verbosity. Can be specified multiple times.
- `-c, --connector <connector>`: The name of the memflow connector to use. - `-c, --connector <connector>`: The name of the memflow connector to use.
- `-a, --connector-args <connector-args>`: Additional arguments to supply to the connector. - `-a, --connector-args <connector-args>`: Additional arguments to supply to the connector.
- `-o, --os <os>`: The name of the target operating system. - `-o, --output <output>`: The output directory to write the generated files to. Default: `output`.
- `-d, --directory <directory>`: The output directory to write the generated files to. Default: `output`.
- `-i, --indent-size <indent-size>`: The number of spaces to use per indentation level. Default: `4`. - `-i, --indent-size <indent-size>`: The number of spaces to use per indentation level. Default: `4`.
- `-h, --help`: Print help. - `-h, --help`: Print help.
- `-V, --version`: Print version. - `-V, --version`: Print version.

View File

@ -5,16 +5,16 @@ use std::{env, fs};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
pub static CONFIG: LazyLock<Config> = LazyLock::new(|| { pub static CONFIG: LazyLock<Config> = LazyLock::new(|| {
let file_name = match env::consts::OS { let file_name = get_config_file_name();
"linux" => "config_linux.json",
"windows" => "config_win.json",
os => panic!("unsupported os: {}", os),
};
let content = fs::read_to_string(file_name).expect("unable to read config file"); let content = fs::read_to_string(&file_name).unwrap_or_else(|_| {
let config: Config = serde_json::from_str(&content).expect("unable to parse config file"); panic!(
"unable to read config file: {}\nmake sure the file is placed in the same directory as the cs2-dumper executable",
file_name
)
});
config serde_json::from_str(&content).expect("unable to parse config file")
}); });
#[derive(Debug, Deserialize, Serialize)] #[derive(Debug, Deserialize, Serialize)]
@ -59,3 +59,18 @@ pub struct Signature {
/// List of operations to perform on the matched address. /// List of operations to perform on the matched address.
pub operations: Vec<Operation>, pub operations: Vec<Operation>,
} }
/// Returns the correct config file name, depending on the target OS.
fn get_config_file_name() -> &'static str {
// Assume that if the user has provided a connector name, they are targetting the Windows
// version of the game.
if env::args().any(|arg| arg.starts_with("--connector") || arg.starts_with("-c")) {
"config_win.json"
} else {
match env::consts::OS {
"linux" => "config_linux.json",
"windows" => "config_win.json",
os => panic!("unsupported os: {}", os),
}
}
}

View File

@ -26,7 +26,7 @@ fn main() -> Result<()> {
let start_time = Instant::now(); let start_time = Instant::now();
let matches = parse_args(); let matches = parse_args();
let (conn_name, conn_args, os_name, indent_size, out_dir) = extract_args(&matches)?; let (conn_name, conn_args, indent_size, out_dir) = extract_args(&matches)?;
// Create the output directory if it doesn't exist. // Create the output directory if it doesn't exist.
fs::create_dir_all(&out_dir)?; fs::create_dir_all(&out_dir)?;
@ -38,7 +38,7 @@ fn main() -> Result<()> {
.builder() .builder()
.connector(&conn_name) .connector(&conn_name)
.args(conn_args) .args(conn_args)
.os(&os_name) .os("win32")
.build()? .build()?
} else { } else {
// Fallback to the native OS layer if no connector name was provided. // Fallback to the native OS layer if no connector name was provided.
@ -86,17 +86,10 @@ fn parse_args() -> ArgMatches {
.required(false), .required(false),
) )
.arg( .arg(
Arg::new("os") Arg::new("output")
.help("The name of the target operating system.")
.long("os")
.short('o')
.required(false),
)
.arg(
Arg::new("directory")
.help("The output directory to write the generated files to.") .help("The output directory to write the generated files to.")
.long("directory") .long("output")
.short('d') .short('o')
.default_value("output") .default_value("output")
.value_parser(value_parser!(PathBuf)) .value_parser(value_parser!(PathBuf))
.required(false), .required(false),
@ -113,9 +106,7 @@ fn parse_args() -> ArgMatches {
.get_matches() .get_matches()
} }
fn extract_args( fn extract_args(matches: &ArgMatches) -> Result<(Option<String>, ConnectorArgs, usize, &PathBuf)> {
matches: &ArgMatches,
) -> Result<(Option<String>, ConnectorArgs, String, usize, &PathBuf)> {
use std::str::FromStr; use std::str::FromStr;
let log_level = match matches.get_count("verbose") { let log_level = match matches.get_count("verbose") {
@ -144,17 +135,8 @@ fn extract_args(
.map(|s| ConnectorArgs::from_str(&s).expect("unable to parse connector arguments")) .map(|s| ConnectorArgs::from_str(&s).expect("unable to parse connector arguments"))
.unwrap_or_default(); .unwrap_or_default();
let os_name = matches
.get_one::<String>("os")
.map(|s| s.to_string())
.unwrap_or_else(|| match env::consts::OS {
"linux" => "linux".to_string(),
"windows" => "win32".to_string(),
os => panic!("unsupported os: {}", os),
});
let indent_size = *matches.get_one::<usize>("indent-size").unwrap(); let indent_size = *matches.get_one::<usize>("indent-size").unwrap();
let out_dir = matches.get_one::<PathBuf>("directory").unwrap(); let out_dir = matches.get_one::<PathBuf>("output").unwrap();
Ok((conn_name, conn_args, os_name, indent_size, out_dir)) Ok((conn_name, conn_args, indent_size, out_dir))
} }