use log::{debug, info}; use tokio::{fs, io::AsyncWriteExt}; use crate::{ config::Config, errors::McError, minecraft::manifests::{Library, Version}, platform::paths, }; /// Download everything required to launch: /// - client jar /// - libraries pub async fn download_all(config: &Config, version: &Version) -> Result<(), McError> { download_client(config, version).await?; download_libraries(config, &version.libraries).await?; Ok(()) } async fn download_client(config: &Config, version: &Version) -> Result<(), McError> { let jar_path = paths::client_jar(config, &version.id)?; if jar_path.exists() { debug!("Client jar already exists"); return Ok(()); } info!("Downloading client {}", version.id); download_file(&version.downloads.client.url, &jar_path).await } async fn download_libraries(config: &Config, libraries: &[Library]) -> Result<(), McError> { for lib in libraries { let Some(artifact) = &lib.downloads.artifact else { continue; }; let lib_path = paths::library_file(config, &artifact.path)?; if lib_path.exists() { continue; } info!("Downloading library {}", artifact.path); download_file(&artifact.url, &lib_path).await?; } Ok(()) } /* ---------------- helper ---------------- */ async fn download_file(url: &str, path: &std::path::Path) -> Result<(), McError> { if let Some(parent) = path.parent() { fs::create_dir_all(parent).await?; } let response = reqwest::get(url).await?; let bytes = response.bytes().await?; let mut file = fs::File::create(path).await?; file.write_all(&bytes).await?; Ok(()) }