This commit is contained in:
Michael Wain 2025-03-13 23:39:17 +03:00
parent e6e515b669
commit a1dba40494
4 changed files with 73 additions and 23 deletions

View File

@ -1,11 +1,12 @@
use core::str; use core::str;
use std::sync::Arc;
use crate::{config::LauncherConfig, minecraft::versions::VersionConfig}; use tokio::sync::{mpsc, Mutex};
use tokio::sync::mpsc::UnboundedReceiver;
use crate::{config::LauncherConfig, minecraft::versions::VersionConfig, util};
#[derive(Default)] #[derive(Default)]
pub struct Launcher { pub struct Launcher {
pub config: LauncherConfig pub config: LauncherConfig,
} }
impl Launcher { impl Launcher {
@ -36,13 +37,28 @@ impl Launcher {
self.save_config(); 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 root = self.config.launcher_dir();
let mut instances = root.clone(); let mut instances = root.clone();
instances.push("instances"); instances.push("instances");
instances.push(config.id); 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) { pub fn init_dirs(&self) {

View File

@ -13,7 +13,7 @@ use winit::window::{Window, WindowId};
use winit::event_loop::ActiveEventLoop; use winit::event_loop::ActiveEventLoop;
use wry::dpi::LogicalSize; use wry::dpi::LogicalSize;
use wry::http::{version, Request, Response}; use wry::http::{version, Request, Response};
use wry::{RequestAsyncResponder, WebView, WebViewBuilder, WebViewBuilderExtWindows}; use wry::{RequestAsyncResponder, WebView, WebViewBuilder};
mod config; mod config;
mod launcher; mod launcher;
@ -76,6 +76,8 @@ async fn main() {
let mut launcher = Launcher::default(); let mut launcher = Launcher::default();
let mut dl_rec = None;
loop { loop {
if let Some((ui_action, params, responder)) = receiver.recv().await { if let Some((ui_action, params, responder)) = receiver.recv().await {
println!("Command: {}", ui_action); println!("Command: {}", ui_action);
@ -129,7 +131,7 @@ async fn main() {
Ok(config ) => { Ok(config ) => {
println!("Config: {}", config.id); println!("Config: {}", config.id);
responder.respond(Response::new(serde_json::to_vec(&UIMessage { params: vec!["show_loading".to_string()] }).unwrap())); 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) => { Err(e) => {
println!("Error: {}", 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()));
}
}
_ => {} _ => {}
} }
} }

View File

@ -1,6 +1,10 @@
use std::sync::{Arc, Mutex};
use rand::{distr::Alphanumeric, Rng}; use rand::{distr::Alphanumeric, Rng};
use reqwest::{Client, Response}; use reqwest::{Client, Response};
use tokio::{fs::File, io::AsyncWriteExt}; 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 { pub fn random_string(len: usize) -> String {
rand::rng() rand::rng()
@ -10,18 +14,26 @@ pub fn random_string(len: usize) -> String {
.collect() .collect()
} }
pub async fn download_file(url: &str, file_path: &str) -> Result<(), Box<dyn std::error::Error>> { pub fn download_file(url: &str, file_path: &str, size: u64, sender: UnboundedSender<(u8, String)>) -> Result<(), Box<dyn std::error::Error>> {
let client = Client::new(); let url = url.to_string();
let mut response: Response = client.get(url).send().await?; let file_path = file_path.to_string();
tokio::spawn( async move {
if response.status().is_success() { let client = Client::new();
let mut file = File::create(file_path).await?; let mut response: Response = client.get(url).send().await.unwrap();
while let Some(chunk) = response.chunk().await? {
file.write_all(&chunk).await?;
}
} else {
println!("Failed to download file: {}", response.status());
}
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(()) Ok(())
} }

View File

@ -393,10 +393,21 @@
showAddSection(); showAddSection();
} else if( params[i] == "set_downloadable_versions" ) { } else if( params[i] == "set_downloadable_versions" ) {
setDownloadableVersions(params.slice(1)); 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() { function downloadSelectedVersion() {
let version = $('#mc-version :selected').text(); let version = $('#mc-version :selected').text();
$.post({url: "download_vanilla", data: JSON.stringify({ params: [version] })}, processParams); $.post({url: "download_vanilla", data: JSON.stringify({ params: [version] })}, processParams);
@ -414,7 +425,7 @@
} }
function signUp() { 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() { function runPortable() {
@ -442,7 +453,11 @@
} }
$( document ).ready(async function() { $( document ).ready(async function() {
$.get("check_installation", processParams) $.get("check_installation", processParams);
setInterval(function() {
$.get("check_download_status", processParams);
}, 200);
}); });
</script> </script>
</body> </body>