- add: launcher for custom uri protocol to allow pass token and server info to the client
This commit is contained in:
@@ -5,6 +5,6 @@ members = [
|
|||||||
"database-service",
|
"database-service",
|
||||||
"packet-service",
|
"packet-service",
|
||||||
"world-service",
|
"world-service",
|
||||||
"utils",
|
"utils", "launcher", "api-service",
|
||||||
]
|
]
|
||||||
resolver = "2"
|
resolver = "2"
|
||||||
|
|||||||
10
launcher/Cargo.toml
Normal file
10
launcher/Cargo.toml
Normal 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
120
launcher/src/main.rs
Normal 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...");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user