summaryrefslogtreecommitdiffstats
path: root/src/launcher.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/launcher.rs')
-rw-r--r--src/launcher.rs71
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();