Added hash verification for assets and librairies
A bit of code (not completed) for downloading custom libraries
This commit is contained in:
parent
5b8effd7c4
commit
5c8682d199
@ -3,10 +3,11 @@ pub mod altarik;
|
||||
|
||||
use std::path::{Path, self, PathBuf};
|
||||
|
||||
use anyhow::{Result, bail, anyhow};
|
||||
use anyhow::{Result, bail};
|
||||
use reqwest::{Client, StatusCode};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use tokio::{fs::{self, File}, io::{AsyncWriteExt, AsyncSeekExt}, sync::mpsc};
|
||||
use sha1::{Digest, Sha1};
|
||||
use tokio::{fs::{self, File}, io::{AsyncWriteExt, AsyncSeekExt, AsyncReadExt}, sync::mpsc};
|
||||
|
||||
use crate::authentification::GameProfile;
|
||||
|
||||
@ -130,6 +131,7 @@ impl<'a> MinecraftClient<'_> {
|
||||
self.download_libraries(lib).await?;
|
||||
self.download_custom_libraries(lib).await?;
|
||||
self.download_assets(asset).await?;
|
||||
self.download_jar().await?;
|
||||
self.opts.log_channel.send(ProgressMessage { p_type: "completed".to_string(), current: 0, total: 0 }).await?;
|
||||
Ok(())
|
||||
}
|
||||
@ -150,7 +152,12 @@ impl<'a> MinecraftClient<'_> {
|
||||
|
||||
let size = file.seek(std::io::SeekFrom::End(0)).await?;
|
||||
file.seek(std::io::SeekFrom::Start(0)).await?;
|
||||
if size != i.downloads.artifact.size {
|
||||
let mut hasher = Sha1::new();
|
||||
let mut content = Vec::new();
|
||||
file.read_to_end(&mut content).await?;
|
||||
hasher.update(content);
|
||||
let hash = hasher.finalize();
|
||||
if size != i.downloads.artifact.size || format!("{:x}", hash) != i.downloads.artifact.sha1.to_lowercase() {
|
||||
let url = i.downloads.artifact.url.clone();
|
||||
|
||||
let mut sha_url = url.clone();
|
||||
@ -185,12 +192,37 @@ impl<'a> MinecraftClient<'_> {
|
||||
async fn download_custom_libraries(&self, lib_dir: &PathBuf) -> Result<()> {
|
||||
if let Some(custom) = &self.custom_details {
|
||||
for i in &custom.libraries {
|
||||
let splited: Vec<&str> = i.name.split(":").collect();
|
||||
if splited.len() == 3 {
|
||||
let file_name = format!("{}-{}.jar", splited[1], splited[2]);
|
||||
let sha256_url = format!("{}.sha256", file_name);
|
||||
let url = format!("{}/{}/{}/{}/{}", i.url, splited[0].replace(".", "/"), splited[1], splited[2], file_name);
|
||||
|
||||
let sha256 = self.reqwest_client
|
||||
.get(sha256_url)
|
||||
.send()
|
||||
.await?
|
||||
.text()
|
||||
.await?;
|
||||
let sep = path::MAIN_SEPARATOR_STR;
|
||||
let p = format!("{}{sep}{}{sep}{}{sep}{}", splited[0].replace(".", sep), splited[1], splited[2], splited[1]);
|
||||
let file_path = lib_dir.join(p);
|
||||
if !file_path.exists() {
|
||||
|
||||
}
|
||||
} else {
|
||||
bail!("Cannot resolve dependency url");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn download_jar(&mut self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// delete and recreate some folder, in particular mods and version folder
|
||||
async fn clear_folder(&self) -> Result<()> {
|
||||
for i in [self.opts.root_path.join("mods"), self.opts.root_path.join("versions")] {
|
||||
@ -232,7 +264,13 @@ impl<'a> MinecraftClient<'_> {
|
||||
let size = file.seek(std::io::SeekFrom::End(0)).await?;
|
||||
file.seek(std::io::SeekFrom::Start(0)).await?;
|
||||
|
||||
if size != value.size {
|
||||
let mut hasher = Sha1::new();
|
||||
let mut content = Vec::new();
|
||||
file.read_to_end(&mut content).await?;
|
||||
hasher.update(content);
|
||||
let hash_file = hasher.finalize();
|
||||
|
||||
if size != value.size || format!("{:x}", hash_file) != value.hash {
|
||||
let url = format!("https://resources.download.minecraft.net/{}/{}", two_hex, hash);
|
||||
let received = self.reqwest_client
|
||||
.get(url)
|
||||
@ -242,14 +280,18 @@ impl<'a> MinecraftClient<'_> {
|
||||
.await?;
|
||||
file.write_all(&received).await?;
|
||||
println!("{} downloaded", value.hash);
|
||||
} // else {
|
||||
// println!("{} already 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?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn launch_minecraft(&mut self) -> Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn should_use_library(library: &Library) -> bool {
|
||||
match &library.rules {
|
||||
Some(rules) => {
|
||||
|
Reference in New Issue
Block a user