diff options
| author | Filip Wandzio <contact@philw.dev> | 2026-02-25 16:10:23 +0100 |
|---|---|---|
| committer | Filip Wandzio <contact@philw.dev> | 2026-02-25 16:10:23 +0100 |
| commit | f7b4b643ebc52a4d72d90d9adbdddc9aa0721e4a (patch) | |
| tree | c96432be342b02bc0409e5b78b6b5d54afcc7cd6 /src/main.rs | |
| parent | 2e10b0713f5369f489d2ababd70108cc359c5d2d (diff) | |
| download | dml-f7b4b643ebc52a4d72d90d9adbdddc9aa0721e4a.tar.gz dml-f7b4b643ebc52a4d72d90d9adbdddc9aa0721e4a.zip | |
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
Diffstat (limited to '')
| -rw-r--r-- | src/main.rs | 105 |
1 files changed, 86 insertions, 19 deletions
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 @@ | |||
| 1 | mod constants; | 1 | //! Main module for the DML Launcher. |
| 2 | mod errors; | 2 | //! |
| 3 | //! This module contains the entry point and orchestrates the full lifecycle | ||
| 4 | //! of the launcher. It coordinates configuration loading, environment setup, | ||
| 5 | //! version management, asset downloading, native extraction, and client launch. | ||
| 6 | //! | ||
| 7 | //! # Workflow | ||
| 8 | //! | ||
| 9 | //! 1. Load environment variables from .env. | ||
| 10 | //! 2. Initialize logging with the warning level. | ||
| 11 | //! 3. Parse command-line arguments using clap. | ||
| 12 | //! 4. Load the persistent configuration file. | ||
| 13 | //! 5. Apply command-line overrides to configuration values. | ||
| 14 | //! 6. Ensure all necessary directories exist. | ||
| 15 | //! 7. Load the version manifest for the selected Minecraft version. | ||
| 16 | //! 8. Download required assets including libraries and client binaries. | ||
| 17 | //! 9. Extract native libraries for the current platform. | ||
| 18 | //! 10. Launch the Minecraft client with the configured JVM arguments and | ||
| 19 | //! session information. | ||
| 20 | //! | ||
| 21 | //! # Error Handling | ||
| 22 | //! | ||
| 23 | //! All operations that can fail propagate errors through the | ||
| 24 | //! McError type. This centralizes error management and | ||
| 25 | //! simplifies the use of the ? operator throughout the launcher. | ||
| 26 | //! | ||
| 27 | //! # Asynchronous Operations | ||
| 28 | //! | ||
| 29 | //! HTTP requests and asset downloads are performed asynchronously using | ||
| 30 | //! tokio to maximize efficiency and reduce blocking. Local file | ||
| 31 | //! operations and the client launch remain synchronous to maintain | ||
| 32 | //! consistency and avoid race conditions. | ||
| 3 | 33 | ||
| 4 | mod config; | 34 | mod config; |
| 35 | mod constants; | ||
| 36 | mod errors; | ||
| 5 | mod minecraft; | 37 | mod minecraft; |
| 6 | mod platform; | 38 | mod platform; |
| 7 | mod util; | 39 | mod util; |
| 8 | 40 | ||
| 9 | use clap::Parser; | 41 | use clap::Parser; |
| 10 | use config::Config; | ||
| 11 | use dotenvy::dotenv; | 42 | use dotenvy::dotenv; |
| 12 | use errors::McError; | 43 | use errors::McError; |
| 13 | use log::{debug, info}; | 44 | use log::LevelFilter::Warn; |
| 45 | use reqwest::Client; | ||
| 46 | use platform::paths::ensure_directories; | ||
| 14 | 47 | ||
| 15 | use crate::minecraft::{ | 48 | use crate::{ |
| 16 | downloads::download_all, extraction::extract_natives, launcher::launch, | 49 | config::ConfigLoader, |
| 17 | manifests, | 50 | minecraft::{ |
| 51 | downloads::download_all_files, extraction::extract_natives, launcher::launch, | ||
| 52 | manifests::load_version, | ||
| 53 | }, | ||
| 18 | }; | 54 | }; |
| 55 | use crate::config::RuntimeConfig; | ||
| 56 | use crate::minecraft::manifests::Version; | ||
| 19 | 57 | ||
| 58 | /// Command-line interface definition. | ||
| 59 | /// | ||
| 60 | /// Provides user-configurable options for the launcher, including | ||
| 61 | /// specifying a Minecraft version, a username, and additional | ||
| 62 | /// JVM arguments. Utilizes clap for argument parsing and validation. | ||
| 20 | #[derive(Parser, Debug)] | 63 | #[derive(Parser, Debug)] |
| 21 | #[command(author, about, disable_version_flag = true)] | 64 | #[command(author, about, disable_version_flag = true)] |
| 22 | struct Cli { | 65 | struct Cli { |
| 66 | /// Optional Minecraft version to launch. | ||
| 23 | #[arg(long)] | 67 | #[arg(long)] |
| 24 | version: Option<String>, | 68 | version: Option<String>, |
| 25 | 69 | ||
| 70 | /// Optional username for the Minecraft session. | ||
| 26 | #[arg(long)] | 71 | #[arg(long)] |
| 27 | username: Option<String>, | 72 | username: Option<String>, |
| 28 | 73 | ||
| 74 | /// Optional JVM arguments to pass to the Minecraft process. | ||
| 75 | /// | ||
| 76 | /// Supports multiple values and allows arguments that begin with hyphens. | ||
| 29 | #[arg(long, num_args(0..), allow_hyphen_values = true)] | 77 | #[arg(long, num_args(0..), allow_hyphen_values = true)] |
| 30 | jvm_args: Vec<String>, | 78 | jvm_args: Vec<String>, |
| 31 | } | 79 | } |
| 32 | 80 | ||
| 81 | /// Launcher entry point. | ||
| 82 | /// | ||
| 83 | /// This asynchronous function orchestrates the entire launch process, | ||
| 84 | /// handling configuration, directory setup, asset management, native | ||
| 85 | /// extraction, and client execution. Returns a Result<(), McError> | ||
| 86 | /// to capture and propagate all errors encountered during execution. | ||
| 87 | /// | ||
| 88 | /// # Steps | ||
| 89 | /// | ||
| 90 | /// 1. Load environment variables from .env. | ||
| 91 | /// 2. Initialize logging with a warning level filter. | ||
| 92 | /// 3. Parse CLI arguments and merge them into the configuration. | ||
| 93 | /// 4. Ensure required directories exist for game data and assets. | ||
| 94 | /// 5. Load the manifest for the specified Minecraft version. | ||
| 95 | /// 6. Build an HTTP client with HTTP/2 support for asset downloads. | ||
| 96 | /// 7. Download all required assets including libraries and client binaries. | ||
| 97 | /// 8. Extract platform-specific native libraries. | ||
| 98 | /// 9. Launch the Minecraft client using the configured JVM arguments and | ||
| 99 | /// session. | ||
| 33 | #[tokio::main] | 100 | #[tokio::main] |
| 34 | async fn main() -> Result<(), McError> { | 101 | async fn main() -> Result<(), McError> { |
| 35 | dotenv().ok(); | 102 | dotenv().ok(); |
| 36 | env_logger::init(); | ||
| 37 | 103 | ||
| 38 | let cli = Cli::parse(); | 104 | env_logger::Builder::new() |
| 39 | let mut config = Config::load()?; | 105 | .filter_level(Warn) |
| 106 | .init(); | ||
| 40 | 107 | ||
| 108 | let cli: Cli = Cli::parse(); | ||
| 109 | let mut config: RuntimeConfig = ConfigLoader::load(None)?; | ||
| 110 | |||
| 41 | if let Some(v) = cli.version { | 111 | if let Some(v) = cli.version { |
| 42 | config.version = v; | 112 | config.version = v; |
| 43 | } | 113 | } |
| 44 | |||
| 45 | if let Some(u) = cli.username { | 114 | if let Some(u) = cli.username { |
| 46 | config.username = u; | 115 | config.username = u; |
| 47 | } | 116 | } |
| @@ -49,16 +118,14 @@ async fn main() -> Result<(), McError> { | |||
| 49 | config.jvm_args = cli.jvm_args; | 118 | config.jvm_args = cli.jvm_args; |
| 50 | } | 119 | } |
| 51 | 120 | ||
| 52 | info!("Final config after CLI overrides: {:?}", config); | 121 | ensure_directories(&config)?; |
| 53 | |||
| 54 | platform::paths::ensure_dirs(&config)?; | ||
| 55 | info!("Using Minecraft version {}", config.version); | ||
| 56 | 122 | ||
| 57 | let version = manifests::load_version(&config).await?; | 123 | let version: Version = load_version(&config).await?; |
| 58 | info!("Loaded version manifest for: {}", version.id); | 124 | let client: Client = Client::builder() |
| 59 | debug!("Main class: {}", version.main_class); | 125 | .http2_prior_knowledge() |
| 126 | .build()?; | ||
| 60 | 127 | ||
| 61 | download_all(&config, &version).await?; | 128 | download_all_files(&client, &config, &version).await?; |
| 62 | extract_natives(&config, &version)?; | 129 | extract_natives(&config, &version)?; |
| 63 | launch(&config, &version)?; | 130 | launch(&config, &version)?; |
| 64 | 131 | ||
