From a1dba40494c1bd51265dea736f4b994834610f40 Mon Sep 17 00:00:00 2001 From: "alterwain@protonmail.com" Date: Thu, 13 Mar 2025 23:39:17 +0300 Subject: [PATCH] Commit --- src/launcher.rs | 28 ++++++++++++++++++++++------ src/main.rs | 11 +++++++++-- src/util.rs | 38 +++++++++++++++++++++++++------------- src/www/portable.html | 19 +++++++++++++++++-- 4 files changed, 73 insertions(+), 23 deletions(-) diff --git a/src/launcher.rs b/src/launcher.rs index c4adc1e..1e59752 100644 --- a/src/launcher.rs +++ b/src/launcher.rs @@ -1,11 +1,12 @@ use core::str; - -use crate::{config::LauncherConfig, minecraft::versions::VersionConfig}; - +use std::sync::Arc; +use tokio::sync::{mpsc, Mutex}; +use tokio::sync::mpsc::UnboundedReceiver; +use crate::{config::LauncherConfig, minecraft::versions::VersionConfig, util}; #[derive(Default)] pub struct Launcher { - pub config: LauncherConfig + pub config: LauncherConfig, } impl Launcher { @@ -36,13 +37,28 @@ impl Launcher { self.save_config(); } - pub async fn new_vanilla_instance(&self, config: VersionConfig) { + pub async fn new_vanilla_instance(&mut self, config: VersionConfig) -> UnboundedReceiver<(u8, String)> { let root = self.config.launcher_dir(); let mut instances = root.clone(); instances.push("instances"); instances.push(config.id); - std::fs::create_dir_all(instances); + std::fs::create_dir_all(&instances); + + instances.push("client.jar"); + + let (sx, rx) = mpsc::unbounded_channel(); + + let client_jar_url = config.downloads.client.url; + + util::download_file(&client_jar_url, instances.to_str().unwrap(), config.downloads.client.size, sx); + + /*for i in 0..config.libraries.len() { + let library = &config.libraries[i]; + + }*/ + + rx } pub fn init_dirs(&self) { diff --git a/src/main.rs b/src/main.rs index 7a0db90..f34d633 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,7 @@ use winit::window::{Window, WindowId}; use winit::event_loop::ActiveEventLoop; use wry::dpi::LogicalSize; use wry::http::{version, Request, Response}; -use wry::{RequestAsyncResponder, WebView, WebViewBuilder, WebViewBuilderExtWindows}; +use wry::{RequestAsyncResponder, WebView, WebViewBuilder}; mod config; mod launcher; @@ -76,6 +76,8 @@ async fn main() { let mut launcher = Launcher::default(); + let mut dl_rec = None; + loop { if let Some((ui_action, params, responder)) = receiver.recv().await { println!("Command: {}", ui_action); @@ -129,7 +131,7 @@ async fn main() { Ok(config ) => { println!("Config: {}", config.id); responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["show_loading".to_string()] }).unwrap())); - launcher.new_vanilla_instance(config).await; + dl_rec = Some(launcher.new_vanilla_instance(config).await); } Err(e) => { println!("Error: {}", e); @@ -138,6 +140,11 @@ async fn main() { } } } + "check_download_status" => { + if let Some((percent, text)) = dl_rec.unwrap().recv().await { + responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["update_downloads".to_string(), text, percent.to_string()] }).unwrap())); + } + } _ => {} } } diff --git a/src/util.rs b/src/util.rs index d523a12..73980d3 100644 --- a/src/util.rs +++ b/src/util.rs @@ -1,6 +1,10 @@ +use std::sync::{Arc, Mutex}; use rand::{distr::Alphanumeric, Rng}; use reqwest::{Client, Response}; use tokio::{fs::File, io::AsyncWriteExt}; +use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender}; +use tokio::sync::{mpsc}; +use crate::launcher::Launcher; pub fn random_string(len: usize) -> String { rand::rng() @@ -10,18 +14,26 @@ pub fn random_string(len: usize) -> String { .collect() } -pub async fn download_file(url: &str, file_path: &str) -> Result<(), Box> { - let client = Client::new(); - let mut response: Response = client.get(url).send().await?; - - if response.status().is_success() { - let mut file = File::create(file_path).await?; - while let Some(chunk) = response.chunk().await? { - file.write_all(&chunk).await?; - } - } else { - println!("Failed to download file: {}", response.status()); - } +pub fn download_file(url: &str, file_path: &str, size: u64, sender: UnboundedSender<(u8, String)>) -> Result<(), Box> { + let url = url.to_string(); + let file_path = file_path.to_string(); + tokio::spawn( async move { + let client = Client::new(); + let mut response: Response = client.get(url).send().await.unwrap(); + if response.status().is_success() { + let mut file = File::create(file_path).await.unwrap(); + let mut cur_size = 0; + while let Some(chunk) = response.chunk().await.unwrap() { + cur_size += chunk.len(); + sender.send((((cur_size / size as usize) * 100) as u8, "Downloading".to_string()) ); + let _ = file.write_all(&chunk).await; + } + } else { + println!("Failed to download file: {}", response.status()); + } + }); Ok(()) -} \ No newline at end of file +} + + diff --git a/src/www/portable.html b/src/www/portable.html index cbc1583..dbcb12f 100644 --- a/src/www/portable.html +++ b/src/www/portable.html @@ -393,10 +393,21 @@ showAddSection(); } else if( params[i] == "set_downloadable_versions" ) { setDownloadableVersions(params.slice(1)); + break; + } else if( params[i] == "update_downloads" ) { + updateDownloads(params.slice(1)); + break; } } } + function updateDownloads(params) { + let text = params[0]; + let percentage = params[1]; + $("#loading-text").html(text); + $("#progress-bar").css("width", percentage+"%"); + } + function downloadSelectedVersion() { let version = $('#mc-version :selected').text(); $.post({url: "download_vanilla", data: JSON.stringify({ params: [version] })}, processParams); @@ -414,7 +425,7 @@ } function signUp() { - $.post({url: "sign_up", data: JSON.stringify({ params: [$("#sign_up_username").val()] }) }, processParams) + $.post({url: "sign_up", data: JSON.stringify({params: [$("#sign_up_username").val()]})}, processParams) } function runPortable() { @@ -442,7 +453,11 @@ } $( document ).ready(async function() { - $.get("check_installation", processParams) + $.get("check_installation", processParams); + + setInterval(function() { + $.get("check_download_status", processParams); + }, 200); });