From cdbf1bdcef4051c3d08b3e32743a9dedf0169cea Mon Sep 17 00:00:00 2001 From: Quentin Legot Date: Mon, 1 May 2023 01:58:37 +0200 Subject: [PATCH] Fix softlock, add assets download --- src-tauri/src/authentification/mod.rs | 2 - src-tauri/src/launcher/manifest.rs | 4 +- src-tauri/src/launcher/mod.rs | 68 ++++++++++++++------------- src-tauri/src/main.rs | 12 ++--- 4 files changed, 44 insertions(+), 42 deletions(-) diff --git a/src-tauri/src/authentification/mod.rs b/src-tauri/src/authentification/mod.rs index eeb9dba..6f0d93e 100644 --- a/src-tauri/src/authentification/mod.rs +++ b/src-tauri/src/authentification/mod.rs @@ -123,7 +123,6 @@ impl Authentification { received = listener => { match received { Ok(received) => { - println!("received code"); second_window.close()?; if received.state != state { @@ -137,7 +136,6 @@ impl Authentification { } }, _ = receiver.recv() => { - println!("window closed"); bail!("You closed the window before completion") } } diff --git a/src-tauri/src/launcher/manifest.rs b/src-tauri/src/launcher/manifest.rs index be1f98e..a18a75f 100644 --- a/src-tauri/src/launcher/manifest.rs +++ b/src-tauri/src/launcher/manifest.rs @@ -64,7 +64,7 @@ pub struct VersionDetail { #[derive(Serialize, Deserialize)] pub struct AssetIndex { - pub id: i32, + pub id: String, pub sha1: String, pub size: usize, #[serde(rename(serialize = "totalSize", deserialize = "totalSize"))] @@ -130,7 +130,7 @@ pub struct AssetsManifest { #[derive(Serialize, Deserialize)] pub struct AssetObject { pub hash: String, - pub size: usize, + pub size: u64, } pub async fn get_version_assets(reqwest: &Client , assets_index: &AssetIndex) -> Result { diff --git a/src-tauri/src/launcher/mod.rs b/src-tauri/src/launcher/mod.rs index df7368b..ecb40e5 100644 --- a/src-tauri/src/launcher/mod.rs +++ b/src-tauri/src/launcher/mod.rs @@ -5,7 +5,7 @@ use std::path::{Path, self, PathBuf}; use anyhow::{Result, bail}; use reqwest::{Client, StatusCode}; use serde::{Serialize, Deserialize}; -use tokio::{fs, io::{AsyncWriteExt, AsyncSeekExt}, sync::mpsc}; +use tokio::{fs::{self, File}, io::{AsyncWriteExt, AsyncSeekExt}, sync::mpsc}; use crate::authentification::GameProfile; @@ -82,7 +82,7 @@ impl<'a> MinecraftClient<'_> { fs::create_dir_all(asset).await?; } self.download_libraries(lib).await?; - self.opts.log_channel.closed().await; + self.download_assets(asset).await?; Ok(()) } @@ -97,15 +97,7 @@ impl<'a> MinecraftClient<'_> { let p = &lib.join(p); fs::create_dir_all(p).await?; let file_path = p.join(filename); - let mut file = if (&file_path).exists() { - let f = fs::File::open(&file_path).await; - match f { - Ok(mut f) => { if f.seek(std::io::SeekFrom::End(0)).await? == i.downloads.artifact.size { f } else { fs::File::create(file_path).await? } }, - Err(err) => bail!(err), - } - } else { - fs::File::create(file_path).await? - }; + let mut file = Self::select_file_option(&file_path, i.downloads.artifact.size).await?; let size = file.seek(std::io::SeekFrom::End(0)).await?; file.seek(std::io::SeekFrom::Start(0)).await?; @@ -136,19 +128,31 @@ impl<'a> MinecraftClient<'_> { } else { println!("{} already downloaded", i.name); } - println!("Sending message"); self.opts.log_channel.send( ProgressMessage { p_type: "libraries".to_string(), current: progress + 1, total }).await?; } Ok(()) } + async fn select_file_option(file_path: &PathBuf, expected_size: u64) -> Result { + if (&file_path).exists() { + let f = fs::File::open(&file_path).await; + match f { + Ok(mut f) => { if f.seek(std::io::SeekFrom::End(0)).await? == expected_size { Ok(f) } else { Ok(fs::File::create(file_path).await?) } }, + Err(err) => bail!(err), + } + } else { + Ok(fs::File::create(file_path).await?) + } + } + /// Filter non necessary librairies for the current OS fn filter_non_necessary_librairies(&mut self) { self.details.libraries.retain(|e| { Self::should_use_library(e) }); } - async fn download_assets(&mut self, object_folder: PathBuf) -> Result<()> { - for (_, (key, value)) in self.assets.objects.iter().enumerate() { + async fn download_assets(&mut self, object_folder: &PathBuf) -> Result<()> { + let total: usize = self.assets.objects.len(); + for (progress, (_, value)) in self.assets.objects.iter().enumerate() { let hash = value.hash.clone(); let two_hex = hash.chars().take(2).collect::(); let hex_folder = object_folder.join(&two_hex); @@ -157,26 +161,26 @@ impl<'a> MinecraftClient<'_> { } let file_path = hex_folder.join(&hash); - let mut file = if (&file_path).exists() { - let f = fs::File::open(&file_path).await; - match f { - Ok(f) => f, - Err(err) => bail!(err), - } - } else { - fs::File::create(file_path).await? - }; + let mut file = Self::select_file_option(&file_path, value.size).await?; + let size = file.seek(std::io::SeekFrom::End(0)).await?; + file.seek(std::io::SeekFrom::Start(0)).await?; - let url = format!("https://resources.download.minecraft.net/{}/{}", two_hex, hash); - let received = self.reqwest_client - .get(url) - .send() - .await? - .bytes() - .await?; - + if size != value.size { + let url = format!("https://resources.download.minecraft.net/{}/{}", two_hex, hash); + let received = self.reqwest_client + .get(url) + .send() + .await? + .bytes() + .await?; + file.write_all(&received).await?; + println!("{} downloaded", value.hash); + } else { + println!("{} already downloaded", value.hash); + } + self.opts.log_channel.send( ProgressMessage { p_type: "assets".to_string(), current: progress + 1, total }).await?; } - bail!("Not yet implemented") + Ok(()) } fn should_use_library(library: &Library) -> bool { diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index 42f38c9..1e4a452 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -45,7 +45,6 @@ async fn login(app: tauri::AppHandle, _window: tauri::Window, state: tauri::Stat #[tauri::command] async fn download(app: tauri::AppHandle, state: tauri::State<'_, Mutex>) -> Result { - println!("starting download"); if let Some(base_dir) = BaseDirs::new() { let data_folder = base_dir.data_dir().join(".altarik_test"); let root_path = data_folder.as_path(); @@ -71,10 +70,8 @@ async fn download(app: tauri::AppHandle, state: tauri::State<'_, Mutex) -> Result { let client = MinecraftClient::new(&opts).await; - match client { + let res = match client { Ok(mut client) => { match client.download_requirements().await { Ok(_) => { @@ -97,13 +94,16 @@ async fn download_libraries(opts: ClientOptions<'_>) -> Result { Err(err) => { Err(err.to_string()) } - } + }; + opts.log_channel.closed().await; + res + } async fn read_channel(mut receiver: mpsc::Receiver, app: tauri::AppHandle) -> Result<()> { loop { match receiver.recv().await { - Some(msg) => { println!("received {:?}", msg); app.emit_all("progress", msg)? }, + Some(msg) => { app.emit_all("progress", msg)? }, None => break Ok(()) } }