From f7b4b643ebc52a4d72d90d9adbdddc9aa0721e4a Mon Sep 17 00:00:00 2001 From: Filip Wandzio Date: Wed, 25 Feb 2026 16:10:23 +0100 Subject: Feat: Refactor core download logic with concurrency and async features Implement basic unit testing Implement automatic java executable switching based on game version Split loader module into smaller modules Implement basic documentation --- src/main.rs | 105 +++++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 19 deletions(-) (limited to 'src/main.rs') diff --git a/src/main.rs b/src/main.rs index e229a3e..4b32c51 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,47 +1,116 @@ -mod constants; -mod errors; +//! Main module for the DML Launcher. +//! +//! This module contains the entry point and orchestrates the full lifecycle +//! of the launcher. It coordinates configuration loading, environment setup, +//! version management, asset downloading, native extraction, and client launch. +//! +//! # Workflow +//! +//! 1. Load environment variables from .env. +//! 2. Initialize logging with the warning level. +//! 3. Parse command-line arguments using clap. +//! 4. Load the persistent configuration file. +//! 5. Apply command-line overrides to configuration values. +//! 6. Ensure all necessary directories exist. +//! 7. Load the version manifest for the selected Minecraft version. +//! 8. Download required assets including libraries and client binaries. +//! 9. Extract native libraries for the current platform. +//! 10. Launch the Minecraft client with the configured JVM arguments and +//! session information. +//! +//! # Error Handling +//! +//! All operations that can fail propagate errors through the +//! McError type. This centralizes error management and +//! simplifies the use of the ? operator throughout the launcher. +//! +//! # Asynchronous Operations +//! +//! HTTP requests and asset downloads are performed asynchronously using +//! tokio to maximize efficiency and reduce blocking. Local file +//! operations and the client launch remain synchronous to maintain +//! consistency and avoid race conditions. mod config; +mod constants; +mod errors; mod minecraft; mod platform; mod util; use clap::Parser; -use config::Config; use dotenvy::dotenv; use errors::McError; -use log::{debug, info}; +use log::LevelFilter::Warn; +use reqwest::Client; +use platform::paths::ensure_directories; -use crate::minecraft::{ - downloads::download_all, extraction::extract_natives, launcher::launch, - manifests, +use crate::{ + config::ConfigLoader, + minecraft::{ + downloads::download_all_files, extraction::extract_natives, launcher::launch, + manifests::load_version, + }, }; +use crate::config::RuntimeConfig; +use crate::minecraft::manifests::Version; +/// Command-line interface definition. +/// +/// Provides user-configurable options for the launcher, including +/// specifying a Minecraft version, a username, and additional +/// JVM arguments. Utilizes clap for argument parsing and validation. #[derive(Parser, Debug)] #[command(author, about, disable_version_flag = true)] struct Cli { + /// Optional Minecraft version to launch. #[arg(long)] version: Option, + /// Optional username for the Minecraft session. #[arg(long)] username: Option, + /// Optional JVM arguments to pass to the Minecraft process. + /// + /// Supports multiple values and allows arguments that begin with hyphens. #[arg(long, num_args(0..), allow_hyphen_values = true)] jvm_args: Vec, } +/// Launcher entry point. +/// +/// This asynchronous function orchestrates the entire launch process, +/// handling configuration, directory setup, asset management, native +/// extraction, and client execution. Returns a Result<(), McError> +/// to capture and propagate all errors encountered during execution. +/// +/// # Steps +/// +/// 1. Load environment variables from .env. +/// 2. Initialize logging with a warning level filter. +/// 3. Parse CLI arguments and merge them into the configuration. +/// 4. Ensure required directories exist for game data and assets. +/// 5. Load the manifest for the specified Minecraft version. +/// 6. Build an HTTP client with HTTP/2 support for asset downloads. +/// 7. Download all required assets including libraries and client binaries. +/// 8. Extract platform-specific native libraries. +/// 9. Launch the Minecraft client using the configured JVM arguments and +/// session. #[tokio::main] async fn main() -> Result<(), McError> { dotenv().ok(); - env_logger::init(); - let cli = Cli::parse(); - let mut config = Config::load()?; + env_logger::Builder::new() + .filter_level(Warn) + .init(); + let cli: Cli = Cli::parse(); + let mut config: RuntimeConfig = ConfigLoader::load(None)?; + if let Some(v) = cli.version { config.version = v; } - if let Some(u) = cli.username { config.username = u; } @@ -49,16 +118,14 @@ async fn main() -> Result<(), McError> { config.jvm_args = cli.jvm_args; } - info!("Final config after CLI overrides: {:?}", config); - - platform::paths::ensure_dirs(&config)?; - info!("Using Minecraft version {}", config.version); + ensure_directories(&config)?; - let version = manifests::load_version(&config).await?; - info!("Loaded version manifest for: {}", version.id); - debug!("Main class: {}", version.main_class); + let version: Version = load_version(&config).await?; + let client: Client = Client::builder() + .http2_prior_knowledge() + .build()?; - download_all(&config, &version).await?; + download_all_files(&client, &config, &version).await?; extract_natives(&config, &version)?; launch(&config, &version)?; -- cgit v1.2.3