Fontend download progress

This commit is contained in:
Samuel Walker 2024-06-23 15:07:25 -06:00
parent 2bb85695c0
commit 6b497d30cd
11 changed files with 128 additions and 38 deletions

View File

@ -8,9 +8,26 @@
"name": "fclauncher",
"version": "0.0.0",
"devDependencies": {
"@tauri-apps/api": "^1.5.6",
"@tauri-apps/cli": "^1"
}
},
"node_modules/@tauri-apps/api": {
"version": "1.5.6",
"resolved": "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.6.tgz",
"integrity": "sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==",
"dev": true,
"license": "Apache-2.0 OR MIT",
"engines": {
"node": ">= 14.6.0",
"npm": ">= 6.6.0",
"yarn": ">= 1.19.1"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/tauri"
}
},
"node_modules/@tauri-apps/cli": {
"version": "1.5.14",
"resolved": "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.14.tgz",

View File

@ -7,6 +7,7 @@
"tauri": "tauri"
},
"devDependencies": {
"@tauri-apps/api": "^1.5.6",
"@tauri-apps/cli": "^1"
}
}

View File

@ -24,7 +24,7 @@ fn ftp_connection(username: &str, password: &str) -> Result<NativeTlsFtpStream,
}
pub fn ftp_retr(file: PathBuf , mut writer: impl Write, mut callback: impl FnMut(usize)) -> Result<bool, FtpError> {
pub fn ftp_retr(window: Option<tauri::Window>, file: PathBuf , mut writer: impl Write, mut callback: impl FnMut(Option<tauri::Window>, usize, usize)) -> Result<bool, FtpError> {
let mut ftp_stream = ftp_connection_anonymous().unwrap();
let file = file.to_str().unwrap().replace("\\", "/");
let size = ftp_stream.size(&file)?;
@ -36,9 +36,10 @@ pub fn ftp_retr(file: PathBuf , mut writer: impl Write, mut callback: impl FnMut
writer.write_all(&mut tx_bytes.split_at(bytes_read).0).unwrap();
total += bytes_read;
if total == size || bytes_read == 0 {
callback(window.clone(), 0, size);
break;
}else{
callback(bytes_read);
callback(window.clone(), bytes_read, size);
}
}
Ok(true)

View File

@ -14,15 +14,13 @@ fn check_java(version: u8) -> bool {
dir.exists()
}
pub fn install_java(version: u8) {
pub fn install_java(version: u8, window: tauri::Window) {
if check_java(version) {
return;
}
let ftp_dir = PathBuf::new().join("java").join(format!("java-{}-{}", version, if env::consts::OS == "windows" { "win.zip" } else {"lin.tar.gz"}));
let mut buff = Cursor::new(vec![]);
let mut total: usize = 0;
let size = ftp_get_size(ftp_dir.clone()).unwrap();
ftp::ftp_retr(ftp_dir, &mut buff, |data| util::download_callback(data, &mut total, size)).unwrap();
ftp::ftp_retr(Some(window), ftp_dir, &mut buff, |window, data, size| util::download_callback(format!("Java {}", version), window,data, size)).unwrap();
std::fs::create_dir_all(get_local_data_directory().join("java").join(format!("java-{}-{}", version, if env::consts::OS == "windows" { "win" } else {"lin"}))).unwrap();
buff.rewind().unwrap();

View File

@ -29,9 +29,10 @@ fn greet(name: &str) -> String {
fn main() {
prism::install_prism();
modpack::get_modpacks();
//prism::install_prism();
tauri::Builder::default()
.invoke_handler(tauri::generate_handler![greet, modpack::get_modpacks, modpack::launch_modpack, prism::launch_prism])
.invoke_handler(tauri::generate_handler![greet, modpack::get_modpacks, modpack::launch_modpack, prism::launch_prism, prism::install_prism])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}

View File

@ -10,6 +10,7 @@ use std::io::{Read, Seek, Write};
use serde_json::Value;
use serde::Serialize;
use serde::Deserialize;
use crate::util;
@ -61,22 +62,22 @@ fn check_modpack_needs_update(id: String) -> bool{
}
#[tauri::command]
pub fn launch_modpack(id: String){
pub async fn launch_modpack(window: tauri::Window, id: String){
if check_modpack_needs_update(id.clone()) {
install_modpack(id.clone());
install_modpack(window, id.clone());
}
// Launch
let mut child = Command::new(get_local_data_directory().join("prism").join(get_prism_executable())).arg("-l").arg(get_modpack_name(id)).spawn().unwrap();
}
fn install_modpack(id: String){
fn install_modpack(window: tauri::Window, id: String){
let versions = get_versions(id.clone());
let path = env::temp_dir().join(format!("{}.mrpack", get_modpack_name(id.clone())));
let mut file = File::create(path.clone()).unwrap();
let ftp_path = PathBuf::new().join(id.clone()).join(versions[versions.len()-1].file.clone().as_str());
println!("Downloading file {}", ftp_path.to_str().unwrap());
ftp::ftp_retr(ftp_path, &mut file, |_| return).unwrap();
ftp::ftp_retr(Some(window.clone()), ftp_path, &mut file, |window, data, size| util::download_callback(get_modpack_name(id.clone()), window, data, size)).unwrap();
let mut child = Command::new(get_local_data_directory().join("prism").join(get_prism_executable())).arg("-I").arg(path).spawn().unwrap();
loop {
let version_path = get_local_data_directory().join("prism").join("instances").join(get_modpack_name(id.clone())).join(".minecraft").join("version.txt");
@ -102,7 +103,7 @@ fn install_modpack(id: String){
}
}
let java = get_java_version(mc_version);
java::install_java(java);
java::install_java(java, window.clone());
let option_path = get_local_data_directory().join("prism").join("instances").join(get_modpack_name(id.clone())).join("instance.cfg");
let mut option_file = File::open(option_path.clone()).unwrap();
@ -132,7 +133,7 @@ pub fn get_modpacks() -> Vec<ModpackEntry> {
static mut modpacks: Vec<ModpackEntry> = Vec::new();
if modpacks.is_empty() {
let mut buf = Cursor::new(vec![]);
ftp::ftp_retr(PathBuf::new().join("modpacks.json"), &mut buf, |_| return);
ftp::ftp_retr(None, PathBuf::new().join("modpacks.json"), &mut buf, |_, _, _| return);
buf.rewind();
let v: Value = serde_json::from_reader(buf).unwrap();
println!("{}", v[0]["name"]);
@ -147,7 +148,7 @@ pub fn get_modpacks() -> Vec<ModpackEntry> {
fn get_versions(id: String) -> Vec<VersionEntry> {
let mut versions: Vec<VersionEntry> = Vec::new();
let mut buf = Cursor::new(vec![]);
ftp::ftp_retr(PathBuf::new().join(id).join("versions.json"), &mut buf, |_| return);
ftp::ftp_retr(None, PathBuf::new().join(id).join("versions.json"), &mut buf, |_, _, _| return);
buf.rewind();
let v: Value = serde_json::from_reader(buf).unwrap();
for version in v.as_array().unwrap() {

View File

@ -3,7 +3,7 @@ use flate2::read::GzDecoder;
use tar::Archive;
use tauri::api::file;
use crate::{ftp, java, system_dirs::{get_local_data_directory, get_prism_executable}};
use crate::{ftp, java, system_dirs::{get_local_data_directory, get_prism_executable}, util};
pub fn check_prism() -> bool {
@ -11,21 +11,19 @@ pub fn check_prism() -> bool {
path.exists()
}
pub fn install_prism() -> Result<(), Box<dyn std::error::Error>>{
#[tauri::command]
pub async fn install_prism(window: tauri::Window){
if check_prism() {
return Ok(());
return;
}
java::install_java(21);
java::install_java(21, window.clone());
let path = PathBuf::new().join("prism").join(format!("prism-{}",if env::consts::OS == "windows" {"win.zip"} else {"lin.tar.gz"}));
let size = ftp::ftp_get_size(path.clone())?;
let size = ftp::ftp_get_size(path.clone()).unwrap();
let mut buff = Cursor::new(vec![]);
let mut total = 0;
ftp::ftp_retr(path, &mut buff, |data| {
total += data;
println!("Downloading Prism: {}MB / {}MB", total/(1024*1024), size/(1024*1024));
}).unwrap();
std::fs::create_dir_all(get_local_data_directory().join("prism"))?;
buff.rewind()?;
ftp::ftp_retr(Some(window.clone()), path, &mut buff, |window: Option<tauri::Window>, data, size| util::download_callback("Prism Launcher".to_string(),window, data, size)).unwrap();
std::fs::create_dir_all(get_local_data_directory().join("prism")).unwrap();
buff.rewind().unwrap();
if env::consts::OS != "windows" {
let tar = GzDecoder::new(buff);
let mut archive = Archive::new(tar);
@ -39,7 +37,7 @@ pub fn install_prism() -> Result<(), Box<dyn std::error::Error>>{
}
let mut buff = Cursor::new(vec![]);
ftp::ftp_retr(PathBuf::new().join("prism").join("prismlauncher.cfg"), &mut buff, |_| return).unwrap();
ftp::ftp_retr(Some(window.clone()), PathBuf::new().join("prism").join("prismlauncher.cfg"), &mut buff, |_, _, _| return).unwrap();
buff.rewind();
let mut file = File::create(get_local_data_directory().join("prism").join("prismlauncher.cfg")).unwrap();
loop {
@ -57,7 +55,6 @@ pub fn install_prism() -> Result<(), Box<dyn std::error::Error>>{
}
Ok(())
}

View File

@ -1,6 +1,30 @@
use std::clone;
pub fn download_callback(count: usize, total: &mut usize, size: usize){
*total += count;
println!("Downloading {}MB / {}MB", *total/(1024*1024), size/(1024*1024));
use serde::Serialize;
#[derive(Clone, Serialize)]
pub struct DownloadStatus {
downloaded: usize,
total: usize,
time_elapsed: usize,
download_name: String
}
pub fn download_callback(download_name: String, window: Option<tauri::Window>, count: usize, size: usize){
unsafe{
static mut total: usize = 0;
total += count;
if let Some(window1) = window.clone() {
window1.emit("download_progress", DownloadStatus{downloaded: total, total: size, time_elapsed: 0, download_name: download_name});
}
println!("Downloading {}MB / {}MB", total/(1024*1024), size/(1024*1024));
if count == 0 {
if let Some(window2) = window {
window2.emit("download_finished", true);
}
total = 0;
}
}
}

View File

@ -12,7 +12,7 @@
<body onload="load();">
<body>
<div class="Logo">
<img src="assets/Title.png" alt="Title" id="Title">
@ -28,6 +28,9 @@
<select name="modSelect" id="Modpacks" class="bg-dark text-white">
</select>
<p id="download_name"></p>
<p id="download_progress"></p>
<button id="launchGame" type="button">Launch Minecraft</button>

View File

@ -1,13 +1,24 @@
const { invoke } = window.__TAURI__.tauri;
const { listen } = window.__TAURI__.event;
//import { listen } from '@tauri-apps/api';
let greetInputEl;
let greetMsgEl;
async function greet() {
// Learn more about Tauri commands at https://tauri.app/v1/guides/features/command
greetMsgEl.textContent = "testing";
//greetMsgEl.textContent = await invoke("greet", { name: greetInputEl.value });
}
const download_progress = listen("download_progress", (progress) => {
console.log("Downloading");
//console.log("Downloaded "+progress.payload.downloaded/(1024*1024) +"MB / " + progress.payload.total/(1024*1024) + "MB");
document.getElementById("download_name").textContent = "Downloading "+progress.payload.download_name;
document.getElementById("download_progress").textContent = progress.payload.downloaded/(1024*1024) + "MB / "+progress.payload.total/(1024*1024)+"MB";
document.getElementById("launchGame").disabled = true;
});
const download_finished = listen("download_finished", (event) => {
document.getElementById("download_name").textContent = "";
document.getElementById("download_progress").textContent = "";
document.getElementById("launchGame").disabled = false;
});
window.addEventListener("DOMContentLoaded", () => {
@ -29,6 +40,7 @@ function load() {
}
window.onload = async function() {
invoke("install_prism");
invoke("get_modpacks").then(addModpacks);
}
@ -48,6 +60,7 @@ function addModpacks(modpacks) {
function gameLaunch() {
var packId = document.getElementById("Modpacks");
var selectedId = packId.value;
document.getElementById("launchGame").disabled = true;
//TODO Launch Game
invoke("launch_modpack", { id: selectedId}).then(window.close);
@ -66,4 +79,4 @@ function gameLaunch() {
//}
//}
//}
//}
//}

34
FCLauncher/yarn.lock Normal file
View File

@ -0,0 +1,34 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@tauri-apps/api@^1.5.6":
version "1.5.6"
resolved "https://registry.npmjs.org/@tauri-apps/api/-/api-1.5.6.tgz"
integrity sha512-LH5ToovAHnDVe5Qa9f/+jW28I6DeMhos8bNDtBOmmnaDpPmJmYLyHdeDblAWWWYc7KKRDg9/66vMuKyq0WIeFA==
"@tauri-apps/cli-linux-x64-gnu@1.5.14":
version "1.5.14"
resolved "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-gnu/-/cli-linux-x64-gnu-1.5.14.tgz"
integrity sha512-kD9v/UwPDuhIgq2TJj/s2/7rqk+vmExVV6xHPKI8vVbIvlNAOZqmx3fpxjej1241vhJ/piGd/m6q6YMWGsL0oQ==
"@tauri-apps/cli-linux-x64-musl@1.5.14":
version "1.5.14"
resolved "https://registry.npmjs.org/@tauri-apps/cli-linux-x64-musl/-/cli-linux-x64-musl-1.5.14.tgz"
integrity sha512-204Drgg9Zx0+THKndqASz4+iPCwqA3gQVF9C0CDIArNXrjPyJjVvW8VP5CHiZYaTNWxlz/ltyxluM6UFWbXNFw==
"@tauri-apps/cli@^1":
version "1.5.14"
resolved "https://registry.npmjs.org/@tauri-apps/cli/-/cli-1.5.14.tgz"
integrity sha512-JOSMKymlg116UdEXSj69eg5p1OtZnQkUE0qIGbtNDO1sk3X/KgBN6+oHBW0BzPStp/W0AjBgrMWCqjHPwEpOug==
optionalDependencies:
"@tauri-apps/cli-darwin-arm64" "1.5.14"
"@tauri-apps/cli-darwin-x64" "1.5.14"
"@tauri-apps/cli-linux-arm-gnueabihf" "1.5.14"
"@tauri-apps/cli-linux-arm64-gnu" "1.5.14"
"@tauri-apps/cli-linux-arm64-musl" "1.5.14"
"@tauri-apps/cli-linux-x64-gnu" "1.5.14"
"@tauri-apps/cli-linux-x64-musl" "1.5.14"
"@tauri-apps/cli-win32-arm64-msvc" "1.5.14"
"@tauri-apps/cli-win32-ia32-msvc" "1.5.14"
"@tauri-apps/cli-win32-x64-msvc" "1.5.14"