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 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) {

View File

@ -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()));
}
}
_ => {}
}
}

View File

@ -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<dyn std::error::Error>> {
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<dyn std::error::Error>> {
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(())
}
}

View File

@ -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);
});
</script>
</body>