diff options
| author | 2025-01-13 20:58:36 -0600 | |
|---|---|---|
| committer | 2025-01-13 20:58:36 -0600 | |
| commit | ff428f36935cefd2b6d8ea6ba4a0572d75d6512d (patch) | |
| tree | cf8b71137247ba74c4a606146d45ec2791725877 /src/launcher.rs | |
| parent | more stuff (diff) | |
library downloads complete
Diffstat (limited to 'src/launcher.rs')
| -rw-r--r-- | src/launcher.rs | 61 |
1 files changed, 47 insertions, 14 deletions
diff --git a/src/launcher.rs b/src/launcher.rs index a849cc5..83ec342 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -3,6 +3,7 @@ mod version; mod profile; mod strsub; mod download; +mod rules; use std::borrow::Cow; use std::collections::HashMap; @@ -12,19 +13,18 @@ use std::fmt::{Display, Formatter}; use std::io::ErrorKind; use std::path::{Path, PathBuf}; use const_format::formatcp; -use futures::TryFutureExt; -use log::{debug, warn}; +use futures::StreamExt; +use log::{debug, info, warn}; use serde::{Deserialize, Serialize}; -use sha1_smol::Sha1; use sysinfo::System; -use tokio::fs::File; use tokio::{fs, io}; -use tokio::io::AsyncReadExt; use version::VersionList; -use profile::{Instance, Profile}; -use crate::launcher::download::{Download, VerifiedDownload}; -use crate::launcher::version::{VersionResolveError, VersionResult}; -use crate::version::{DownloadInfo, Library, OSRestriction, OperatingSystem}; +use download::{MultiDownloader, PhaseDownloadError, VerifiedDownload}; +use rules::{CompatCheck, IncompatibleError}; +use version::{VersionResolveError, VersionResult}; +use crate::version::{Library, OSRestriction, OperatingSystem}; + +pub use profile::{Instance, Profile}; #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct Settings { @@ -95,9 +95,14 @@ pub struct Launcher { #[derive(Debug)] pub enum LaunchError { + // version resolution errors UnknownVersion(String), LoadVersion(Box<dyn Error>), - ResolveVersion(VersionResolveError) + ResolveVersion(VersionResolveError), + IncompatibleVersion(IncompatibleError), + + // library errors + LibraryDirError(PathBuf, io::Error) } impl Display for LaunchError { @@ -105,7 +110,9 @@ impl Display for LaunchError { match &self { LaunchError::UnknownVersion(id) => write!(f, "unknown version id: {id}"), LaunchError::LoadVersion(e) => write!(f, "error loading remote version: {e}"), - LaunchError::ResolveVersion(e) => write!(f, "error resolving remote version: {e}") + LaunchError::ResolveVersion(e) => write!(f, "error resolving remote version: {e}"), + LaunchError::IncompatibleVersion(e) => e.fmt(f), + LaunchError::LibraryDirError(path, e) => write!(f, "failed to create library directory {}: {}", path.display(), e) } } } @@ -115,6 +122,8 @@ impl Error for LaunchError { match &self { LaunchError::LoadVersion(e) => Some(e.as_ref()), LaunchError::ResolveVersion(e) => Some(e), + LaunchError::IncompatibleVersion(e) => Some(e), + LaunchError::LibraryDirError(_, e) => Some(e), _ => None } } @@ -196,10 +205,34 @@ impl Launcher { }; let ver = self.versions.resolve_version(ver.as_ref()).await.map_err(|e| LaunchError::ResolveVersion(e))?; + ver.rules_apply(&self.system_info, |_| false).map_err(|e| LaunchError::IncompatibleVersion(e))?; + + let mut libs = Vec::new(); + let mut downloads = Vec::new(); + + for lib in ver.libraries.values() { + if lib.rules_apply(&self.system_info, |_| false).is_err() { + continue; + } + + libs.push(lib); + if let Some(dl) = self.libraries.create_download(lib, self.system_info.os) { + dl.make_dirs().await.map_err(|e| LaunchError::LibraryDirError(dl.get_path().to_path_buf(), e))?; + downloads.push(dl); + } + } + + // TODO: offline + info!("Downloading {} libraries...", downloads.len()); + + let mut multi = MultiDownloader::new(downloads); + let dl: Vec<_> = multi.perform().await.collect().await; + info!("amogus: {dl:?}"); - // todo: make a list of all the required libraries + // todo: offline mode - todo!() + //todo!() + Ok(()) } } @@ -264,7 +297,7 @@ impl LibraryRepository { } fn create_download(&self, lib: &Library, os: OperatingSystem) -> Option<VerifiedDownload> { - let classifier = lib.natives.as_ref()?.get(&os).map(|s| s.as_str()); + let classifier = lib.natives.as_ref().map_or(None, |n| n.get(&os)).map(|s| s.as_str()); if lib.url.is_some() || lib.downloads.is_none() { // TODO: derive download URL in this situation? |
