forked from Berry-Dash/launcher
More downloading stuff
This commit is contained in:
@@ -1,12 +1,21 @@
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
|
||||
use base64::{Engine, engine::general_purpose};
|
||||
use std::{fs::{create_dir_all, File}, io::{copy, BufReader}, path::PathBuf};
|
||||
use futures_util::stream::StreamExt;
|
||||
use std::{
|
||||
fs::{File, create_dir_all},
|
||||
io::{BufReader, copy},
|
||||
path::PathBuf,
|
||||
process::Command,
|
||||
};
|
||||
use tauri::{AppHandle, Emitter, Manager};
|
||||
use tauri_plugin_decorum::WebviewWindowExt;
|
||||
use tauri_plugin_dialog::{DialogExt, MessageDialogKind};
|
||||
use tokio::{io::AsyncWriteExt, task::spawn_blocking};
|
||||
use zip::ZipArchive;
|
||||
use futures_util::stream::StreamExt;
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
use std::{fs, os::unix::fs::PermissionsExt};
|
||||
#[cfg(target_os = "windows")]
|
||||
use tauri_plugin_decorum::WebviewWindowExt;
|
||||
|
||||
pub async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> zip::result::ZipResult<()> {
|
||||
spawn_blocking(move || {
|
||||
@@ -35,7 +44,12 @@ pub async fn unzip_to_dir(zip_path: PathBuf, out_dir: PathBuf) -> zip::result::Z
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
async fn download(app: AppHandle, url: String, name: String) -> Result<(), String> {
|
||||
async fn download(
|
||||
app: AppHandle,
|
||||
url: String,
|
||||
name: String,
|
||||
executable: String,
|
||||
) -> Result<(), String> {
|
||||
app.emit("download-started", &url).unwrap();
|
||||
|
||||
let client = reqwest::Client::new();
|
||||
@@ -47,12 +61,17 @@ async fn download(app: AppHandle, url: String, name: String) -> Result<(), Strin
|
||||
|
||||
let downloads_path = app.path().app_local_data_dir().unwrap().join("downloads");
|
||||
let game_path = app.path().app_local_data_dir().unwrap().join("game");
|
||||
|
||||
let download_part_path = downloads_path.join(format!("{}.part", name));
|
||||
let download_zip_path = downloads_path.join(format!("{}.zip", name));
|
||||
let executable_path = game_path.join(&name).join(&executable);
|
||||
|
||||
let _ = tokio::fs::create_dir_all(&downloads_path).await;
|
||||
if let Ok(true) = tokio::fs::try_exists(&game_path.join(&name)).await {
|
||||
let _ = tokio::fs::remove_dir_all(&game_path.join(&name)).await;
|
||||
if let Ok(true) = tokio::fs::try_exists(&game_path.join(name.clone())).await {
|
||||
let _ = tokio::fs::remove_dir_all(&game_path.join(name.clone())).await;
|
||||
}
|
||||
let _ = tokio::fs::create_dir_all(&game_path.join(&name)).await;
|
||||
let mut file = tokio::fs::File::create(downloads_path.join(format!("{}.part", name))).await.unwrap();
|
||||
let mut file = tokio::fs::File::create(download_part_path).await.unwrap();
|
||||
|
||||
while let Some(chunk) = stream.next().await {
|
||||
let chunk = chunk.map_err(|e| e.to_string())?;
|
||||
@@ -71,23 +90,71 @@ async fn download(app: AppHandle, url: String, name: String) -> Result<(), Strin
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
tokio::fs::rename(downloads_path.join(format!("{}.part", name)), downloads_path.join(format!("{}.zip", name))).await.unwrap();
|
||||
unzip_to_dir(downloads_path.join(format!("{}.zip", name)), game_path.join(&name)).await.map_err(|e| e.to_string())?;
|
||||
tokio::fs::remove_file(downloads_path.join(format!("{}.zip", name))).await.unwrap();
|
||||
tokio::fs::rename(
|
||||
downloads_path.join(format!("{}.part", name)),
|
||||
download_zip_path.clone(),
|
||||
)
|
||||
.await
|
||||
.unwrap();
|
||||
unzip_to_dir(download_zip_path.clone(), game_path.join(&name))
|
||||
.await
|
||||
.map_err(|e| e.to_string())?;
|
||||
tokio::fs::remove_file(download_zip_path.clone())
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
{
|
||||
let mut perms = fs::metadata(&executable_path).unwrap().permissions();
|
||||
perms.set_mode(0o755);
|
||||
fs::set_permissions(executable_path, perms).unwrap();
|
||||
}
|
||||
|
||||
app.emit("download-finished", &url).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
fn launch_game(app: AppHandle, name: String, executable: String) {
|
||||
let game_folder = app
|
||||
.path()
|
||||
.app_local_data_dir()
|
||||
.unwrap()
|
||||
.join("game")
|
||||
.join(&name);
|
||||
let game_path = game_folder.join(&executable);
|
||||
if !game_path.exists() {
|
||||
app.dialog()
|
||||
.message(format!("Executable \"{}\" not found.\n\nTry reinstalling the game or make a support request in the Community link on the sidebar.", game_path.display().to_string()))
|
||||
.kind(MessageDialogKind::Error)
|
||||
.title("Game not found")
|
||||
.show(|_| {});
|
||||
return;
|
||||
}
|
||||
match Command::new(&game_path).current_dir(&game_folder).spawn() {
|
||||
Ok(_) => println!("Game launched successfully."),
|
||||
Err(e) => {
|
||||
app.dialog()
|
||||
.message(format!("Failed to load game:\n{}\n\nTry reinstalling the game or make a support request in the Community link on the sidebar.", e))
|
||||
.kind(MessageDialogKind::Error)
|
||||
.title("Failed to launch game")
|
||||
.show(|_| {});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
#[allow(unused_variables)]
|
||||
tauri::Builder::default()
|
||||
.plugin(tauri_plugin_dialog::init())
|
||||
.plugin(tauri_plugin_fs::init())
|
||||
.plugin(tauri_plugin_decorum::init())
|
||||
.plugin(tauri_plugin_os::init())
|
||||
.plugin(tauri_plugin_opener::init())
|
||||
.invoke_handler(tauri::generate_handler![download])
|
||||
.invoke_handler(tauri::generate_handler![download, launch_game])
|
||||
.setup(|app| {
|
||||
#[cfg(target_os = "windows")] {
|
||||
#[cfg(target_os = "windows")]
|
||||
{
|
||||
let main_window = app.get_webview_window("main").unwrap();
|
||||
main_window.create_overlay_titlebar().unwrap();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user