Added downloading java
This commit is contained in:
parent
6ec89497cb
commit
affa6d8535
25
src-tauri/Cargo.lock
generated
25
src-tauri/Cargo.lock
generated
@ -68,6 +68,17 @@ version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bddcadddf5e9015d310179a59bb28c4d4b9920ad0f11e8e14dbadf654890c9a6"
|
||||
|
||||
[[package]]
|
||||
name = "async-trait"
|
||||
version = "0.1.73"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bc00ceb34980c03614e35a3a4e218276a0a824e911d07651cd0d858a51e8c0f0"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.37",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "atk"
|
||||
version = "0.15.1"
|
||||
@ -1593,6 +1604,7 @@ dependencies = [
|
||||
"reqwest",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha256",
|
||||
"tauri",
|
||||
"tauri-build",
|
||||
"tokio",
|
||||
@ -2890,6 +2902,19 @@ dependencies = [
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha256"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7895c8ae88588ccead14ff438b939b0c569cd619116f14b4d13fdff7b8333386"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"bytes",
|
||||
"hex",
|
||||
"sha2",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sharded-slab"
|
||||
version = "0.1.6"
|
||||
|
@ -26,6 +26,7 @@ warp = "0.3.3"
|
||||
anyhow = "1.0.66"
|
||||
rand = "0.8.5"
|
||||
directories = "5.0.0"
|
||||
sha256 = "1.4.0"
|
||||
|
||||
[features]
|
||||
# by default Tauri runs in production mode
|
||||
|
@ -106,6 +106,7 @@ pub enum OSName {
|
||||
Windows
|
||||
}
|
||||
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct LibraryArtifact {
|
||||
pub path: String,
|
||||
|
@ -6,11 +6,11 @@ use std::path::{Path, self, PathBuf};
|
||||
use anyhow::{Result, bail};
|
||||
use reqwest::{Client, StatusCode};
|
||||
use serde::{Serialize, Deserialize};
|
||||
use tokio::{fs::{self, File}, io::{AsyncWriteExt, AsyncSeekExt}, sync::mpsc};
|
||||
use tokio::{fs::{self, File, OpenOptions}, io::{AsyncWriteExt, AsyncSeekExt}, sync::mpsc};
|
||||
|
||||
use crate::authentification::GameProfile;
|
||||
|
||||
use self::manifest::{VersionDetail, get_version_manifest, get_version_from_manifest, get_version_detail, Library, OSName, get_version_assets, AssetsManifest};
|
||||
use self::{manifest::{VersionDetail, get_version_manifest, get_version_from_manifest, get_version_detail, Library, OSName, get_version_assets, AssetsManifest}, altarik::Chapter};
|
||||
|
||||
|
||||
#[cfg(target_os="windows")]
|
||||
@ -20,6 +20,9 @@ const ACTUAL_OS: OSName = OSName::Linux;
|
||||
#[cfg(target_os="macos")]
|
||||
const ACTUAL_OS: OSName = OSName::MacOsX;
|
||||
|
||||
#[cfg(not(any(target_arch="x86_64", target_arch="x86")))]
|
||||
compile_error!("Your architecture is not supported");
|
||||
|
||||
#[derive(Clone, serde::Serialize, Debug)]
|
||||
pub struct ProgressMessage {
|
||||
p_type: String,
|
||||
@ -32,6 +35,7 @@ pub struct ClientOptions<'a> {
|
||||
pub log_channel: mpsc::Sender<ProgressMessage>,
|
||||
pub root_path: &'a Path,
|
||||
pub java_path: &'a Path,
|
||||
/// deprecated, will be remove
|
||||
pub version_number: String,
|
||||
pub version_type: VersionType,
|
||||
// version_custom: String, // for a next update
|
||||
@ -73,7 +77,8 @@ impl<'a> MinecraftClient<'_> {
|
||||
let folders = vec![
|
||||
self.opts.root_path.join("libraries"),
|
||||
self.opts.root_path.join("assets").join("objects"),
|
||||
self.opts.root_path.join("assets").join("indexes")
|
||||
self.opts.root_path.join("assets").join("indexes"),
|
||||
self.opts.root_path.join("runtime").join("download"),
|
||||
];
|
||||
let mut tasks = Vec::with_capacity(folders.len());
|
||||
for folder in folders {
|
||||
@ -102,18 +107,73 @@ impl<'a> MinecraftClient<'_> {
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn download_requirements(&mut self) -> Result<()> {
|
||||
pub async fn download_requirements(&mut self, chapter: Chapter) -> Result<()> {
|
||||
// create root folder if it doesn't exist
|
||||
self.create_dirs().await?;
|
||||
let lib = &self.opts.root_path.join("libraries");
|
||||
let asset = &self.opts.root_path.join("assets").join("objects");
|
||||
self.save_version_index().await?;
|
||||
self.download_java(chapter).await?;
|
||||
self.download_libraries(lib).await?;
|
||||
self.download_assets(asset).await?;
|
||||
self.opts.log_channel.send(ProgressMessage { p_type: "completed".to_string(), current: 0, total: 0 }).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn download_java(&mut self, chapter: Chapter) -> Result<()> {
|
||||
let download_path = self.opts.root_path.join("runtime").join("download");
|
||||
// let extract_path = self.opts.root_path.join("runtime");
|
||||
let (url, extension) = match ACTUAL_OS {
|
||||
OSName::Linux => {
|
||||
(chapter.java.platform.linux, "tar.gz")
|
||||
},
|
||||
OSName::Windows => {
|
||||
(chapter.java.platform.win32, "zip")
|
||||
},
|
||||
_ => {
|
||||
bail!("Your current is not supported")
|
||||
}
|
||||
};
|
||||
let url = match url {
|
||||
Some(url) => url,
|
||||
None => bail!("No available executable available for your platform")
|
||||
};
|
||||
|
||||
let filepath = download_path.join(format!("{}.{}", url.x64.name.clone(), extension));
|
||||
let mut should_download = false;
|
||||
if !filepath.exists() {
|
||||
should_download = true;
|
||||
} else {
|
||||
let hash = sha256::try_digest(filepath.clone());
|
||||
match hash {
|
||||
Ok(hash) => {
|
||||
if hash != url.x64.sha256sum {
|
||||
println!("Hash of java archive is not correct, redownloading");
|
||||
should_download = true;
|
||||
}
|
||||
},
|
||||
Err(_) => should_download = true
|
||||
}
|
||||
}
|
||||
if should_download {
|
||||
println!("Downloading java");
|
||||
if filepath.exists() {
|
||||
fs::remove_file(filepath.clone()).await?; // remove content before writing and appending to it
|
||||
}
|
||||
let mut file = OpenOptions::new()
|
||||
.write(true)
|
||||
.create(true)
|
||||
.open(filepath)
|
||||
.await?;
|
||||
let b = self.reqwest_client.get(url.x64.link.clone()).send().await?.bytes().await?;
|
||||
file.write(&b).await?;
|
||||
println!("{} downloaded", url.x64.name)
|
||||
} else {
|
||||
println!("{} already downloaded", url.x64.name)
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn download_libraries(&mut self, lib: &PathBuf) -> Result<()> {
|
||||
self.filter_non_necessary_librairies();
|
||||
let total = self.details.libraries.len();
|
||||
|
@ -11,7 +11,7 @@ use std::sync::Mutex;
|
||||
use authentification::{Authentification, Prompt, GameProfile};
|
||||
use anyhow::Result;
|
||||
use directories::BaseDirs;
|
||||
use launcher::{MinecraftClient, ClientOptions, ProgressMessage, altarik::AltarikManifest};
|
||||
use launcher::{MinecraftClient, ClientOptions, ProgressMessage, altarik::{AltarikManifest, Chapter}};
|
||||
use reqwest::Client;
|
||||
use tauri::Manager;
|
||||
use tokio::sync::mpsc;
|
||||
@ -62,7 +62,23 @@ async fn load_altarik_manifest(state: tauri::State<'_, Mutex<CustomState>>) -> R
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn download(game_version: String, app: tauri::AppHandle, state: tauri::State<'_, Mutex<CustomState>>) -> Result<String, String> {
|
||||
async fn download(selected_chapter: usize, app: tauri::AppHandle, state: tauri::State<'_, Mutex<CustomState>>) -> Result<String, String> {
|
||||
let chapter = match state.lock() {
|
||||
Ok(lock) => {
|
||||
match &lock.1 {
|
||||
Some(manifest) => {
|
||||
match manifest.chapters.get(selected_chapter) {
|
||||
Some(val) => {
|
||||
val.clone()
|
||||
},
|
||||
None => return Err("Selected chapter doesn't exist".to_string())
|
||||
}
|
||||
},
|
||||
None => return Err("Cannot load altarik manifest".to_string())
|
||||
}
|
||||
},
|
||||
Err(err) => return Err(err.to_string())
|
||||
};
|
||||
if let Some(base_dir) = BaseDirs::new() {
|
||||
let data_folder = base_dir.data_dir().join(".altarik_test");
|
||||
let root_path = data_folder.as_path();
|
||||
@ -80,14 +96,14 @@ async fn download(game_version: String, app: tauri::AppHandle, state: tauri::Sta
|
||||
log_channel: sender.clone(),
|
||||
root_path,
|
||||
java_path: &java_path.as_path(),
|
||||
version_number: game_version,
|
||||
version_number: chapter.minecraft_version.clone(),
|
||||
version_type: launcher::VersionType::Release,
|
||||
memory_min: "2G".to_string(),
|
||||
memory_max: "4G".to_string(),
|
||||
};
|
||||
drop(sender);
|
||||
let res = tokio::join!(
|
||||
download_libraries(opts),
|
||||
download_libraries(opts, chapter),
|
||||
read_channel(receiver, app),
|
||||
);
|
||||
res.0
|
||||
@ -97,11 +113,11 @@ async fn download(game_version: String, app: tauri::AppHandle, state: tauri::Sta
|
||||
}
|
||||
|
||||
|
||||
async fn download_libraries(opts: ClientOptions<'_>) -> Result<String, String> {
|
||||
async fn download_libraries(opts: ClientOptions<'_>, chapter: Chapter) -> Result<String, String> {
|
||||
let client = MinecraftClient::new(&opts).await;
|
||||
let res = match client {
|
||||
Ok(mut client) => {
|
||||
match client.download_requirements().await {
|
||||
match client.download_requirements(chapter).await {
|
||||
Ok(_) => {
|
||||
Ok("Content downloaded".to_string())
|
||||
},
|
||||
|
@ -55,7 +55,7 @@ export default function LoginPage() {
|
||||
async function download() {
|
||||
if(isLogged) {
|
||||
if(selectedChapter !== -1 && altarikManifest !== undefined) {
|
||||
invoke("download", { gameVersion: altarikManifest?.chapters[selectedChapter].minecraftVersion }).then(value => {
|
||||
invoke("download", { selectedChapter: selectedChapter }).then(value => {
|
||||
setGreetMessage(String(value))
|
||||
}).catch(err => {
|
||||
console.log("An error occured")
|
||||
|
Reference in New Issue
Block a user