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 std::path::{Path, self, PathBuf};
|
||||||
|
|
||||||
use anyhow::{Result, bail, anyhow};
|
use anyhow::{Result, bail};
|
||||||
use reqwest::{Client, StatusCode};
|
use reqwest::{Client, StatusCode};
|
||||||
use serde::{Serialize, Deserialize};
|
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;
|
use crate::authentification::GameProfile;
|
||||||
|
|
||||||
@ -130,6 +131,7 @@ impl<'a> MinecraftClient<'_> {
|
|||||||
self.download_libraries(lib).await?;
|
self.download_libraries(lib).await?;
|
||||||
self.download_custom_libraries(lib).await?;
|
self.download_custom_libraries(lib).await?;
|
||||||
self.download_assets(asset).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?;
|
self.opts.log_channel.send(ProgressMessage { p_type: "completed".to_string(), current: 0, total: 0 }).await?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -150,7 +152,12 @@ impl<'a> MinecraftClient<'_> {
|
|||||||
|
|
||||||
let size = file.seek(std::io::SeekFrom::End(0)).await?;
|
let size = file.seek(std::io::SeekFrom::End(0)).await?;
|
||||||
file.seek(std::io::SeekFrom::Start(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 url = i.downloads.artifact.url.clone();
|
||||||
|
|
||||||
let mut sha_url = 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<()> {
|
async fn download_custom_libraries(&self, lib_dir: &PathBuf) -> Result<()> {
|
||||||
if let Some(custom) = &self.custom_details {
|
if let Some(custom) = &self.custom_details {
|
||||||
for i in &custom.libraries {
|
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(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn download_jar(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// delete and recreate some folder, in particular mods and version folder
|
/// delete and recreate some folder, in particular mods and version folder
|
||||||
async fn clear_folder(&self) -> Result<()> {
|
async fn clear_folder(&self) -> Result<()> {
|
||||||
for i in [self.opts.root_path.join("mods"), self.opts.root_path.join("versions")] {
|
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?;
|
let size = file.seek(std::io::SeekFrom::End(0)).await?;
|
||||||
file.seek(std::io::SeekFrom::Start(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 url = format!("https://resources.download.minecraft.net/{}/{}", two_hex, hash);
|
||||||
let received = self.reqwest_client
|
let received = self.reqwest_client
|
||||||
.get(url)
|
.get(url)
|
||||||
@ -242,14 +280,18 @@ impl<'a> MinecraftClient<'_> {
|
|||||||
.await?;
|
.await?;
|
||||||
file.write_all(&received).await?;
|
file.write_all(&received).await?;
|
||||||
println!("{} downloaded", value.hash);
|
println!("{} downloaded", value.hash);
|
||||||
} // else {
|
} else {
|
||||||
// println!("{} already downloaded", value.hash);
|
println!("{} already downloaded", value.hash);
|
||||||
// }
|
}
|
||||||
self.opts.log_channel.send( ProgressMessage { p_type: "assets".to_string(), current: progress + 1, total }).await?;
|
self.opts.log_channel.send( ProgressMessage { p_type: "assets".to_string(), current: progress + 1, total }).await?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn launch_minecraft(&mut self) -> Result<()> {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn should_use_library(library: &Library) -> bool {
|
fn should_use_library(library: &Library) -> bool {
|
||||||
match &library.rules {
|
match &library.rules {
|
||||||
Some(rules) => {
|
Some(rules) => {
|
||||||
|
Reference in New Issue
Block a user