diff --git a/crates/molotov-bootstrap/src/launcher.rs b/crates/molotov-bootstrap/src/launcher.rs new file mode 100644 index 0000000..234cf41 --- /dev/null +++ b/crates/molotov-bootstrap/src/launcher.rs @@ -0,0 +1,67 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +use crate::error::MolotovError; +use crate::fflags::{FastFlagManager, PresetProfile}; +use crate::region::ServerRegion; +use crate::sandbox::SandboxConfig; +use crate::watchdog::{LaunchStatus, LaunchWatchdog}; +use std::path::PathBuf; + +#[derive(Debug, Clone)] +pub struct LaunchOptions { + pub place_id: Option, + pub safe_mode: bool, + pub region: ServerRegion, + pub instance_id: String, +} + +pub struct LaunchPlan { + pub place_id: Option, + pub fflags_path: PathBuf, + pub sandbox_config: SandboxConfig, + pub is_safe_mode: bool, +} + +pub struct Launcher { + base_dir: PathBuf, +} + +impl Launcher { + pub fn new(base_dir: PathBuf) -> Self { + Self { base_dir } + } + + pub fn prepare_launch(&self, options: LaunchOptions) -> Result { + let state_file = self.base_dir.join("launch_state.json"); + let mut watchdog = LaunchWatchdog::new(state_file); + + // Check if Safe Mode is required + let activate_safe_mode = options.safe_mode || watchdog.status() == LaunchStatus::RequiresSafeMode; + watchdog.record_start()?; + + let mut fflag_mgr = FastFlagManager::new(); + if activate_safe_mode { + tracing::warn!("Launcher: launching in SAFE MODE with minimal default flags"); + fflag_mgr.apply_preset(PresetProfile::Default); + } else { + fflag_mgr.apply_preset(PresetProfile::LowVram); + options.region.apply_to_fflags(&mut fflag_mgr); + } + + let fflags_path = self.base_dir.join("ClientAppSettings.json"); + fflag_mgr.export_client_app_settings(&fflags_path)?; + + let sandbox_config = SandboxConfig { + instance_id: options.instance_id.clone(), + data_dir: self.base_dir.join("instances").join(&options.instance_id).join("data"), + config_dir: self.base_dir.join("instances").join(&options.instance_id).join("config"), + nice_priority: -5, + }; + + Ok(LaunchPlan { + place_id: options.place_id, + fflags_path, + sandbox_config, + is_safe_mode: activate_safe_mode, + }) + } +} diff --git a/crates/molotov-bootstrap/src/lib.rs b/crates/molotov-bootstrap/src/lib.rs index ac0930e..e71e14e 100644 --- a/crates/molotov-bootstrap/src/lib.rs +++ b/crates/molotov-bootstrap/src/lib.rs @@ -4,6 +4,7 @@ pub mod cdn; pub mod cleaner; pub mod error; pub mod fflags; +pub mod launcher; pub mod mods; pub mod region; pub mod sandbox; diff --git a/crates/molotov-bootstrap/tests/launcher_test.rs b/crates/molotov-bootstrap/tests/launcher_test.rs new file mode 100644 index 0000000..6f07026 --- /dev/null +++ b/crates/molotov-bootstrap/tests/launcher_test.rs @@ -0,0 +1,22 @@ +// SPDX-License-Identifier: GPL-3.0-or-later +use molotov_bootstrap::launcher::{LaunchOptions, Launcher}; +use molotov_bootstrap::region::ServerRegion; +use tempfile::tempdir; + +#[test] +fn test_launcher_prepare_flow() { + let temp = tempdir().unwrap(); + let root = temp.path().to_path_buf(); + + let launcher = Launcher::new(root); + let options = LaunchOptions { + place_id: Some(1818), + safe_mode: false, + region: ServerRegion::Europe, + instance_id: "default".to_string(), + }; + + let plan = launcher.prepare_launch(options).expect("Should prepare launch plan"); + assert!(plan.fflags_path.exists()); + assert_eq!(plan.place_id, Some(1818)); +}