From 1b2d6bdac2514c6457fca246e2dc08b56548f64aeae4a12a468bb4a2ef51f90e Mon Sep 17 00:00:00 2001 From: raven <7156279+RavenX8@users.noreply.github.com> Date: Sun, 15 Dec 2024 01:41:42 -0500 Subject: [PATCH] - update: code cleanup - update: reworked how the launch params are parsed --- launcher/src/launcher.rs | 70 +++++++++++++++++++++++++ launcher/src/main.rs | 110 +++++---------------------------------- 2 files changed, 83 insertions(+), 97 deletions(-) create mode 100644 launcher/src/launcher.rs diff --git a/launcher/src/launcher.rs b/launcher/src/launcher.rs new file mode 100644 index 0000000..6e94d73 --- /dev/null +++ b/launcher/src/launcher.rs @@ -0,0 +1,70 @@ +use crate::{format_shell_command, wait_for_keypress}; +use std::borrow::Cow; +use std::env; +use std::process::{exit, Command, Stdio}; +use tracing::{debug, error, info, warn}; +use url::Url; + +pub(crate) fn launch_game(url: String) { + let exe_dir_path = env::current_exe().unwrap().parent().unwrap().to_path_buf(); + + // Change the working directory + if let Err(e) = env::set_current_dir(exe_dir_path) { + error!("Failed to set working directory: {}", e); + wait_for_keypress(); + exit(1); + } + + // Parse the URL + match Url::parse(&url) { + Ok(parsed_url) => { + let params = parsed_url.query_pairs(); + let game_executable = "./TRose.exe"; + let mut command = Command::new(game_executable); + command.arg("@TRIGGER_SOFT@"); + + let mut is_direct = false; + for (key, value) in params { + debug!("Query pairs: [{}, {}]", key, value); + + match key { + Cow::Borrowed("ip") => { + command.arg("_server").arg(value.to_string()); + } + Cow::Borrowed("port") => { + command.arg("_port").arg(value.to_string()); + } + Cow::Borrowed("otp") => { + is_direct = true; + command.arg("_direct").arg("_otp").arg(value.to_string()); + } + Cow::Borrowed("username") => { + command.arg("_userid").arg(value.to_string()); + } + Cow::Borrowed("password") => { + if !is_direct { + command.arg("_pass").arg(value.to_string()); + } + } + _ => { + warn!("Unexpected parameter: [{}, {}]", key, value); + } + } + } + + command + .stdin(Stdio::null()) + .stdout(Stdio::null()) + .stderr(Stdio::null()); + + info!("Executing: {:?}", format_shell_command(&command)); + + // Check if the game launched successfully + match command.spawn() { + Ok(_) => info!("Game launched successfully!"), + Err(e) => error!("Failed to launch the game: {}", e), + } + } + Err(e) => error!("Failed to parse URL: {}", e), + } +} diff --git a/launcher/src/main.rs b/launcher/src/main.rs index c719cd3..eecb041 100644 --- a/launcher/src/main.rs +++ b/launcher/src/main.rs @@ -1,9 +1,9 @@ -use std::path::{Path, PathBuf}; -use std::process::{exit, Command, Stdio}; +mod launcher; + use clap::{Parser, Subcommand}; -use std::{env, io}; +use std::process::{Command}; +use std::{io}; use tracing::{debug, error, info, Level}; -use url::Url; #[derive(Parser, Debug)] #[command(version, about, long_about = None)] @@ -12,17 +12,15 @@ struct Args { action: Commands, #[arg(short, long, action = clap::ArgAction::Count)] - verbose: u8 + verbose: u8, } #[derive(Subcommand, Debug)] enum Commands { #[command(name = "launch")] - Launch { - url: String, - }, + Launch { url: String }, #[command(name = "update")] - Update + Update, } fn main() -> Result<(), Box> { @@ -30,18 +28,18 @@ fn main() -> Result<(), Box> { let verbose = match args.verbose { 0 => Level::INFO, 1 => Level::DEBUG, - _ => Level::TRACE + _ => Level::TRACE, }; + // Set our logging level tracing_subscriber::fmt().with_max_level(verbose).init(); - + let action = args.action; - match action { Commands::Launch { url } => { debug!("launching with URL {}", url); - launch_game(url); - }, + launcher::launch_game(url); + } Commands::Update => { error!("Update action not implemented"); return Err("Update action not implemented".into()); @@ -51,88 +49,6 @@ fn main() -> Result<(), Box> { Ok(()) } -fn launch_game(url: String) { - - let exe_dir_path = env::current_exe().unwrap().parent().unwrap().to_path_buf(); - // let working_directory = - // env::var("GAME_CLIENT_PATH").unwrap_or_else(|_| "D:/rose_osirose-new-x64".to_string()); - - // Change the working directory - if let Err(e) = env::set_current_dir(exe_dir_path) { - error!("Failed to set working directory: {}", e); - wait_for_keypress(); - exit(1); - } - - // Parse the URL - match Url::parse(&url) { - Ok(parsed_url) => { - // Extract the "otp" parameter - let otp = parsed_url - .query_pairs() - .find(|(key, _)| key == "otp") - .map(|(_, value)| value.to_string()); - let ip = parsed_url - .query_pairs() - .find(|(key, _)| key == "ip") - .map(|(_, value)| value.to_string()); - let username = parsed_url - .query_pairs() - .find(|(key, _)| key == "username") - .map(|(_, value)| value.to_string()); - let port = parsed_url - .query_pairs() - .find(|(key, _)| key == "port") - .map(|(_, value)| value.to_string()) - .unwrap_or("4000".to_string()); - - // Ensure required parameters are present - if otp.is_none() || ip.is_none() || username.is_none() { - error!("Missing required parameters: otp, ip, or username"); - wait_for_keypress(); - return; - } - - // Unwrap the parameters - let otp = otp.unwrap(); - let ip = ip.unwrap(); - let username = username.unwrap(); - - info!("Launching game with:"); - info!(" OTP: {}", otp); - info!(" IP: {}", ip); - info!(" Username: {}", username); - - // Construct the game client command - let game_executable = "./TRose.exe"; - let mut command = Command::new(game_executable); - command - .arg("@TRIGGER_SOFT@") - .arg("_direct") - .arg("_server") - .arg(ip) - .arg("_port") - .arg(port) - .arg("_userid") - .arg(username) - .arg("_otp") - .arg(otp) - .stdin(Stdio::null()) - .stdout(Stdio::null()) - .stderr(Stdio::null()); - - info!("Executing: {:?}", format_shell_command(&command)); - - // Check if the game launched successfully - match command.spawn() { - Ok(_) => info!("Game launched successfully!"), - Err(e) => error!("Failed to launch the game: {}", e), - } - } - Err(e) => error!("Failed to parse URL: {}", e), - } -} - fn wait_for_keypress() { // Wait for a keypress info!("Press Enter to close the launcher..."); @@ -147,4 +63,4 @@ fn format_shell_command(command: &Command) -> String { .collect(); format!("{} {}", executable, args.join(" ")) -} \ No newline at end of file +}