diff options
| author | 2025-01-07 03:43:43 -0600 | |
|---|---|---|
| committer | 2025-01-07 03:43:43 -0600 | |
| commit | 5d68d164d9a7bff8f3015257f25eb71c44829ddf (patch) | |
| tree | c6fa8bd5e7c4dc4e14268f3c34138b5bf92d3746 /src/launcher.rs | |
| parent | idr what I changed (diff) | |
untested moment (remove reqwest)
Diffstat (limited to 'src/launcher.rs')
| -rw-r--r-- | src/launcher.rs | 71 |
1 files changed, 65 insertions, 6 deletions
diff --git a/src/launcher.rs b/src/launcher.rs index 4c4f762..5dfc68a 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -2,16 +2,21 @@ mod constants; mod version; mod profile; mod strsub; +mod download; +mod request; use std::borrow::Cow; use std::collections::HashMap; use std::env::consts::{ARCH, OS}; use std::error::Error; use std::fmt::{Display, Formatter}; +use std::io::ErrorKind; use std::path::{Path, PathBuf}; use serde::{Deserialize, Serialize}; -use sha1_smol::Digest; +use sha1_smol::Sha1; use sysinfo::System; +use tokio::fs::File; +use tokio::io::AsyncReadExt; use version::VersionList; use profile::{Instance, Profile}; use crate::launcher::version::{VersionResolveError, VersionResult}; @@ -57,14 +62,22 @@ pub enum LaunchError { impl Display for LaunchError { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { match &self { - LaunchError::UnknownVersion(id) => write!(f, "Unknown version ID: {id}"), + 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}") } } } -impl Error for LaunchError {} +impl Error for LaunchError { + fn cause(&self) -> Option<&dyn Error> { + match &self { + LaunchError::LoadVersion(e) => Some(e.as_ref()), + LaunchError::ResolveVersion(e) => Some(e), + _ => None + } + } +} impl Launcher { // FIXME: more descriptive error type por favor @@ -133,6 +146,23 @@ impl Launcher { } } +#[derive(Debug, Clone)] +enum LibraryError { + InvalidName(String), + IOError(ErrorKind) +} + +impl Display for LibraryError { + fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { + match self { + LibraryError::InvalidName(name) => write!(f, "invalid name: {name}"), + LibraryError::IOError(e) => write!(f, "io error reading library: {e}"), + } + } +} + +impl Error for LibraryError {} + impl LibraryRepository { fn get_artifact_base_dir(name: &str) -> Option<PathBuf> { let end_of_gid = name.find(':')?; @@ -167,8 +197,37 @@ impl LibraryRepository { Some(p) } - async fn should_redownload(&self, lib: &Library, classifier: Option<&str>) -> Result<bool, Box<dyn Error>> { - let path = Self::get_artifact_path(lib.name.as_str(), classifier); + async fn should_redownload(&self, lib: &Library, classifier: Option<&str>) -> Result<bool, LibraryError> { + let path = Self::get_artifact_path(lib.name.as_str(), classifier) + .map_or_else(|| Err(LibraryError::InvalidName(lib.name.clone())), |p| Ok(p))?; + + let mut f = match File::open(path).await { + Ok(f) => f, + Err(e) => return match e.kind() { + ErrorKind::NotFound => Ok(true), + e => Err(LibraryError::IOError(e)) + } + }; + + let mut data = [0u8; 4096]; + let mut sha1 = Sha1::new(); + + loop { + let n = match f.read(&mut data).await { + Ok(n) => n, + Err(e) => return match e.kind() { + ErrorKind::Interrupted => continue, + kind => Err(LibraryError::IOError(kind)) + } + }; + + if n == 0 { + break; // we reached the end of the file + } + + sha1.update(&data[..n]); + } + todo!() } @@ -185,7 +244,7 @@ impl SystemInfo { let mut os_version = System::os_version().unwrap_or_default(); if os == OperatingSystem::Windows && (os_version.starts_with("10") || os_version.starts_with("11")) { - os_version.replace_range(..2, "10.0"); // java expects this funny business... + os_version.replace_range(..2, "10.0"); // minecraft expects this funny business... } let mut arch = ARCH.to_owned(); |
