This repository has been archived on 2026-10-10. You can view files and clone it, but cannot push or open issues or pull requests.
molotov/crates/molotov-bootstrap/src/launcher.rs

88 lines
3 KiB
Rust

// SPDX-License-Identifier: GPL-3.0-or-later
use crate::error::MolotovError;
use crate::fflags::{FastFlagManager, FlagValue, 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<u64>,
pub safe_mode: bool,
pub region: ServerRegion,
pub instance_id: String,
pub fps_cap: Option<i64>,
pub vram_skip_mips: bool,
}
pub struct LaunchPlan {
pub place_id: Option<u64>,
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<LaunchPlan, MolotovError> {
let state_file = self.base_dir.join("launch_state.json");
let watchdog = LaunchWatchdog::new(state_file);
// Check if Safe Mode is required without modifying state
let activate_safe_mode = options.safe_mode || watchdog.status() == LaunchStatus::RequiresSafeMode;
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);
// Apply custom user settings
if let Some(fps) = options.fps_cap {
fflag_mgr.set_flag("DFIntTaskSchedulerTargetFps", FlagValue::Integer(fps));
}
if options.vram_skip_mips {
fflag_mgr.set_flag("FIntDebugTextureManagerSkipMips", FlagValue::Integer(1));
}
}
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,
})
}
pub fn record_launch_start(&self) -> Result<(), MolotovError> {
let state_file = self.base_dir.join("launch_state.json");
let mut watchdog = LaunchWatchdog::new(state_file);
watchdog.record_start()
}
pub fn record_launch_success(&self) -> Result<(), MolotovError> {
let state_file = self.base_dir.join("launch_state.json");
let mut watchdog = LaunchWatchdog::new(state_file);
watchdog.record_success()
}
}