summaryrefslogtreecommitdiffstats
path: root/src/launcher.rs
diff options
context:
space:
mode:
authorLibravatar bigfoot547 <[email protected]>2025-01-13 20:58:36 -0600
committerLibravatar bigfoot547 <[email protected]>2025-01-13 20:58:36 -0600
commitff428f36935cefd2b6d8ea6ba4a0572d75d6512d (patch)
treecf8b71137247ba74c4a606146d45ec2791725877 /src/launcher.rs
parentmore stuff (diff)
library downloads complete
Diffstat (limited to 'src/launcher.rs')
-rw-r--r--src/launcher.rs61
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?