- add: launcher for custom uri protocol to allow pass token and server info to the client

This commit is contained in:
2024-12-14 01:52:27 -05:00
parent 4f826d7da5
commit 949a931914
3 changed files with 131 additions and 1 deletions

View File

@@ -5,6 +5,6 @@ members = [
"database-service",
"packet-service",
"world-service",
"utils",
"utils", "launcher", "api-service",
]
resolver = "2"

10
launcher/Cargo.toml Normal file
View File

@@ -0,0 +1,10 @@
[package]
name = "launcher"
version = "0.1.0"
edition = "2021"
[dependencies]
shell-escape = "0.1.5"
tracing = "0.1.41"
tracing-subscriber = "0.3.19"
url = "2.5.4"

120
launcher/src/main.rs Normal file
View File

@@ -0,0 +1,120 @@
use std::path::Path;
use std::process::{exit, Command, Stdio};
use std::str::FromStr;
use std::{env, io};
use tracing::{error, info, Level};
use url::Url;
fn wait_for_keypress() {
// Wait for a keypress
info!("Press Enter to close the launcher...");
let _ = io::stdin().read_line(&mut String::new());
}
fn format_shell_command(command: &Command) -> String {
let executable = command.get_program().to_string_lossy();
let args: Vec<String> = command
.get_args()
.map(|arg| shell_escape::escape(arg.to_string_lossy()).into_owned())
.collect();
format!("{} {}", executable, args.join(" "))
}
fn main() {
tracing_subscriber::fmt()
.with_max_level(
Level::from_str(&env::var("LOG_LEVEL").unwrap_or_else(|_| "info".to_string()))
.unwrap_or_else(|_| Level::INFO),
)
.init();
// Get the full command-line arguments (the URL is passed as the first argument after the executable)
let args: Vec<String> = env::args().collect();
if args.len() < 2 {
error!("Usage: osirose-launcher <url>");
wait_for_keypress();
return;
}
let url = &args[1];
let working_directory =
env::var("GAME_CLIENT_PATH").unwrap_or_else(|_| "D:/rose_osirose-new-x64".to_string());
// 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);
// Change the working directory
if let Err(e) = env::set_current_dir(Path::new(&working_directory)) {
eprintln!("Failed to set working directory: {}", e);
wait_for_keypress();
exit(1);
}
// 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),
}
info!("Launcher is closing...");
}