use std::net::SocketAddr; use godot::{classes::Os, prelude::*}; use crate::{ game::{Game, GameManager}, net::network_manager::NetworkManager, }; #[derive(Debug, Default, Clone)] pub struct Options { host: Option, join: Option, map: Option, } impl Options { fn process_arg(&mut self, arg: &str, params: Vec) { match arg { "host" => { if let Some(port) = params.first() && let Ok(port) = port.parse::() { self.host = Some(port); } } "join" => { if let Some(addr) = params.first() && let Ok(addr) = addr.parse::() { self.join = Some(addr); } } "map" => { if let Some(map_name) = params.first() { self.map = Some(map_name.clone()); } } _ => {} } } } #[derive(GodotClass)] #[class(base=Node3D, init)] pub struct CliParser { pub opts: Option, base: Base, } #[godot_api] impl INode3D for CliParser { fn ready(&mut self) { let mut options = Options::default(); let args = Os::singleton() .get_cmdline_user_args() .to_vec() .iter() .map(|v| v.to_string()) .collect::>(); let mut current_command: Option = None; let mut params: Vec = Vec::new(); for arg in args { if arg.starts_with("--") { if let Some(command) = current_command.take() { options.process_arg(&command, params.drain(..).collect::>()); } let (_, arg) = arg.split_at(2); current_command = Some(arg.to_string()); } else { params.push(arg); } } if let Some(command) = current_command.take() { options.process_arg(&command, params.drain(..).collect::>()); } self.opts = Some(options.clone()); NetworkManager::singleton() .bind_mut() .signals() .lobby_joined() .connect_other(self, |s| s.on_join_lobby()); if let Some(port) = options.host { NetworkManager::singleton().bind_mut().host(port); } else if let Some(addr) = options.join { NetworkManager::singleton().bind_mut().join_directly(addr); } } } impl CliParser { pub fn on_join_lobby(&self) { if let Some(opts) = &self.opts && let Some(map_name) = &opts.map && let Some(mut game) = Game::singleton() { let map = GameManager::singleton() .bind() .maps .iter_shared() .enumerate() .find(|(_, map)| { map.bind().name.to_string().to_lowercase() == map_name.to_lowercase() }); if let Some((map_idx, _)) = map { game.bind_mut().forced_map_selection = true; game.bind_mut().change_map_selection(map_idx as u8, true); } } } }