mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-10 04:22:13 +10:00
chore: commit changes, still bad
This commit is contained in:
1
src-tauri/Cargo.lock
generated
1
src-tauri/Cargo.lock
generated
@ -4337,7 +4337,6 @@ checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
|
|||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-channel",
|
|
||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"h2 0.4.11",
|
"h2 0.4.11",
|
||||||
|
|||||||
@ -105,7 +105,7 @@ features = ["other_errors"] # You can also use "yaml_enc"
|
|||||||
[dependencies.reqwest]
|
[dependencies.reqwest]
|
||||||
version = "0.12"
|
version = "0.12"
|
||||||
default-features = false
|
default-features = false
|
||||||
features = ["json", "http2", "blocking", "rustls-tls-webpki-roots", "stream"]
|
features = ["json", "http2", "rustls-tls-webpki-roots", "stream"]
|
||||||
|
|
||||||
[dependencies.serde]
|
[dependencies.serde]
|
||||||
version = "1"
|
version = "1"
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
use log::{debug, error};
|
use log::{debug, error};
|
||||||
use tauri::AppHandle;
|
use tauri::AppHandle;
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
use crate::AppState;
|
use crate::DropFunctionState;
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn quit(app: tauri::AppHandle, state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
|
pub async fn quit<>(app: tauri::AppHandle, state: tauri::State<'_, DropFunctionState<'_>>) -> Result<(), ()> {
|
||||||
cleanup_and_exit(&app, &state).await;
|
cleanup_and_exit(&app, &state).await;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -13,7 +12,7 @@ pub async fn quit(app: tauri::AppHandle, state: tauri::State<'_, Mutex<AppState<
|
|||||||
|
|
||||||
pub async fn cleanup_and_exit(
|
pub async fn cleanup_and_exit(
|
||||||
app: &AppHandle,
|
app: &AppHandle,
|
||||||
state: &tauri::State<'_, Mutex<AppState<'_>>>,
|
state: &tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) {
|
) {
|
||||||
debug!("cleaning up and exiting application");
|
debug!("cleaning up and exiting application");
|
||||||
let download_manager = state.lock().await.download_manager.clone();
|
let download_manager = state.lock().await.download_manager.clone();
|
||||||
|
|||||||
@ -1,10 +1,8 @@
|
|||||||
use tokio::sync::Mutex;
|
use crate::DropFunctionState;
|
||||||
|
|
||||||
use crate::AppState;
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn fetch_state(
|
pub async fn fetch_state(
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<String, String> {
|
) -> Result<String, String> {
|
||||||
let guard = state.lock().await;
|
let guard = state.lock().await;
|
||||||
let cloned_state = serde_json::to_string(&guard.clone()).map_err(|e| e.to_string())?;
|
let cloned_state = serde_json::to_string(&guard.clone()).map_err(|e| e.to_string())?;
|
||||||
|
|||||||
@ -1,22 +1,20 @@
|
|||||||
use tokio::sync::Mutex;
|
use crate::{database::models::data::DownloadableMetadata, DropFunctionState};
|
||||||
|
|
||||||
use crate::{database::models::data::DownloadableMetadata, AppState};
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn pause_downloads(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
|
pub async fn pause_downloads(state: tauri::State<'_, DropFunctionState<'_>>) -> Result<(), ()> {
|
||||||
state.lock().await.download_manager.pause_downloads();
|
state.lock().await.download_manager.pause_downloads();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn resume_downloads(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
|
pub async fn resume_downloads(state: tauri::State<'_, DropFunctionState<'_>>) -> Result<(), ()> {
|
||||||
state.lock().await.download_manager.resume_downloads();
|
state.lock().await.download_manager.resume_downloads();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn move_download_in_queue(
|
pub async fn move_download_in_queue(
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
old_index: usize,
|
old_index: usize,
|
||||||
new_index: usize,
|
new_index: usize,
|
||||||
) -> Result<(), ()> {
|
) -> Result<(), ()> {
|
||||||
@ -29,7 +27,7 @@ pub async fn move_download_in_queue(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn cancel_game(state: tauri::State<'_, Mutex<AppState<'_>>>, meta: DownloadableMetadata) -> Result<(), ()> {
|
pub async fn cancel_game(state: tauri::State<'_, DropFunctionState<'_>>, meta: DownloadableMetadata) -> Result<(), ()> {
|
||||||
state.lock().await.download_manager.cancel(meta);
|
state.lock().await.download_manager.cancel(meta);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use std::{
|
|||||||
use ::futures::future::join_all;
|
use ::futures::future::join_all;
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, info, warn};
|
||||||
use tauri::{AppHandle, Emitter};
|
use tauri::{AppHandle, Emitter};
|
||||||
use tokio::{spawn, sync::Mutex, task::JoinHandle};
|
use tokio::{runtime::Runtime, sync::Mutex};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::models::data::DownloadableMetadata,
|
database::models::data::DownloadableMetadata,
|
||||||
@ -75,9 +75,10 @@ pub struct DownloadManagerBuilder {
|
|||||||
progress: CurrentProgressObject,
|
progress: CurrentProgressObject,
|
||||||
status: Arc<Mutex<DownloadManagerStatus>>,
|
status: Arc<Mutex<DownloadManagerStatus>>,
|
||||||
app_handle: AppHandle,
|
app_handle: AppHandle,
|
||||||
|
runtime: Runtime,
|
||||||
|
|
||||||
current_download_agent: Option<DownloadAgent>, // Should be the only download agent in the map with the "Go" flag
|
current_download_agent: Option<DownloadAgent>, // Should be the only download agent in the map with the "Go" flag
|
||||||
current_download_thread: Mutex<Option<JoinHandle<()>>>,
|
current_download_thread: Mutex<Option<tokio::task::JoinHandle<()>>>,
|
||||||
active_control_flag: Option<DownloadThreadControl>,
|
active_control_flag: Option<DownloadThreadControl>,
|
||||||
}
|
}
|
||||||
impl DownloadManagerBuilder {
|
impl DownloadManagerBuilder {
|
||||||
@ -95,13 +96,24 @@ impl DownloadManagerBuilder {
|
|||||||
sender: command_sender.clone(),
|
sender: command_sender.clone(),
|
||||||
progress: active_progress.clone(),
|
progress: active_progress.clone(),
|
||||||
app_handle,
|
app_handle,
|
||||||
|
runtime: tokio::runtime::Builder::new_multi_thread()
|
||||||
|
.worker_threads(1)
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap(),
|
||||||
|
|
||||||
current_download_agent: None,
|
current_download_agent: None,
|
||||||
current_download_thread: Mutex::new(None),
|
current_download_thread: Mutex::new(None),
|
||||||
active_control_flag: None,
|
active_control_flag: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
let terminator = spawn(async{ manager.manage_queue().await });
|
let terminator = tauri::async_runtime::spawn(async {
|
||||||
|
if let Err(_err) = manager.manage_queue().await {
|
||||||
|
panic!("download manager exited with error");
|
||||||
|
} else {
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
DownloadManager::new(terminator, queue, active_progress, command_sender)
|
DownloadManager::new(terminator, queue, active_progress, command_sender)
|
||||||
}
|
}
|
||||||
@ -110,7 +122,10 @@ impl DownloadManagerBuilder {
|
|||||||
*self.status.lock().await = status;
|
*self.status.lock().await = status;
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn remove_and_cleanup_front_download(&mut self, meta: &DownloadableMetadata) -> DownloadAgent {
|
async fn remove_and_cleanup_front_download(
|
||||||
|
&mut self,
|
||||||
|
meta: &DownloadableMetadata,
|
||||||
|
) -> DownloadAgent {
|
||||||
self.download_queue.pop_front();
|
self.download_queue.pop_front();
|
||||||
let download_agent = self.download_agent_registry.remove(meta).unwrap();
|
let download_agent = self.download_agent_registry.remove(meta).unwrap();
|
||||||
self.cleanup_current_download().await;
|
self.cleanup_current_download().await;
|
||||||
@ -126,7 +141,6 @@ impl DownloadManagerBuilder {
|
|||||||
|
|
||||||
let mut download_thread_lock = self.current_download_thread.lock().await;
|
let mut download_thread_lock = self.current_download_thread.lock().await;
|
||||||
*download_thread_lock = None;
|
*download_thread_lock = None;
|
||||||
drop(download_thread_lock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn stop_and_wait_current_download(&self) {
|
async fn stop_and_wait_current_download(&self) {
|
||||||
@ -237,12 +251,20 @@ impl DownloadManagerBuilder {
|
|||||||
self.active_control_flag = Some(download_agent.control_flag().await);
|
self.active_control_flag = Some(download_agent.control_flag().await);
|
||||||
self.current_download_agent = Some(download_agent.clone());
|
self.current_download_agent = Some(download_agent.clone());
|
||||||
|
|
||||||
|
info!("fetched control flag");
|
||||||
|
|
||||||
let sender = self.sender.clone();
|
let sender = self.sender.clone();
|
||||||
|
|
||||||
|
info!("cloned sender");
|
||||||
|
|
||||||
let mut download_thread_lock = self.current_download_thread.lock().await;
|
let mut download_thread_lock = self.current_download_thread.lock().await;
|
||||||
|
info!("acquired download thread lock");
|
||||||
let app_handle = self.app_handle.clone();
|
let app_handle = self.app_handle.clone();
|
||||||
|
|
||||||
*download_thread_lock = Some(spawn(async move {
|
info!("starting download agent thread");
|
||||||
|
|
||||||
|
*download_thread_lock = Some(self.runtime.spawn(async move {
|
||||||
|
info!("started download agent thread");
|
||||||
match download_agent.download(&app_handle).await {
|
match download_agent.download(&app_handle).await {
|
||||||
// Ok(true) is for completed and exited properly
|
// Ok(true) is for completed and exited properly
|
||||||
Ok(true) => {
|
Ok(true) => {
|
||||||
@ -285,6 +307,8 @@ impl DownloadManagerBuilder {
|
|||||||
self.set_status(DownloadManagerStatus::Downloading).await;
|
self.set_status(DownloadManagerStatus::Downloading).await;
|
||||||
let active_control_flag = self.active_control_flag.clone().unwrap();
|
let active_control_flag = self.active_control_flag.clone().unwrap();
|
||||||
active_control_flag.set(DownloadThreadControlFlag::Go);
|
active_control_flag.set(DownloadThreadControlFlag::Go);
|
||||||
|
|
||||||
|
// download_thread_lock.take().unwrap().await;
|
||||||
}
|
}
|
||||||
async fn manage_stop_signal(&mut self) {
|
async fn manage_stop_signal(&mut self) {
|
||||||
debug!("got signal Stop");
|
debug!("got signal Stop");
|
||||||
@ -311,7 +335,8 @@ impl DownloadManagerBuilder {
|
|||||||
current_agent.on_error(&self.app_handle, &error).await;
|
current_agent.on_error(&self.app_handle, &error).await;
|
||||||
|
|
||||||
self.stop_and_wait_current_download().await;
|
self.stop_and_wait_current_download().await;
|
||||||
self.remove_and_cleanup_front_download(¤t_agent.metadata()).await;
|
self.remove_and_cleanup_front_download(¤t_agent.metadata())
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
self.set_status(DownloadManagerStatus::Error).await;
|
self.set_status(DownloadManagerStatus::Error).await;
|
||||||
}
|
}
|
||||||
@ -365,18 +390,17 @@ impl DownloadManagerBuilder {
|
|||||||
}
|
}
|
||||||
async fn push_ui_queue_update(&self) {
|
async fn push_ui_queue_update(&self) {
|
||||||
let queue = &self.download_queue.read();
|
let queue = &self.download_queue.read();
|
||||||
let queue_objs = join_all(queue
|
let queue_objs = join_all(queue.iter().map(async |key| {
|
||||||
.iter()
|
let val = self.download_agent_registry.get(key).unwrap();
|
||||||
.map(async |key| {
|
QueueUpdateEventQueueData {
|
||||||
let val = self.download_agent_registry.get(key).unwrap();
|
meta: DownloadableMetadata::clone(key),
|
||||||
QueueUpdateEventQueueData {
|
status: val.status().await,
|
||||||
meta: DownloadableMetadata::clone(key),
|
progress: val.progress().await.get_progress(),
|
||||||
status: val.status().await,
|
current: val.progress().await.sum(),
|
||||||
progress: val.progress().await.get_progress(),
|
max: val.progress().await.get_max(),
|
||||||
current: val.progress().await.sum(),
|
}
|
||||||
max: val.progress().await.get_max(),
|
}))
|
||||||
}
|
.await;
|
||||||
})).await;
|
|
||||||
|
|
||||||
let event_data = QueueUpdateEvent { queue: queue_objs };
|
let event_data = QueueUpdateEvent { queue: queue_objs };
|
||||||
self.app_handle.emit("update_queue", event_data).unwrap();
|
self.app_handle.emit("update_queue", event_data).unwrap();
|
||||||
|
|||||||
@ -9,7 +9,7 @@ use std::{
|
|||||||
|
|
||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use tokio::task::{JoinError, JoinHandle};
|
use tauri::async_runtime::JoinHandle;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::models::data::DownloadableMetadata,
|
database::models::data::DownloadableMetadata,
|
||||||
@ -170,7 +170,7 @@ impl DownloadManager {
|
|||||||
pub fn resume_downloads(&self) {
|
pub fn resume_downloads(&self) {
|
||||||
self.command_sender.send(DownloadManagerSignal::Go).unwrap();
|
self.command_sender.send(DownloadManagerSignal::Go).unwrap();
|
||||||
}
|
}
|
||||||
pub async fn ensure_terminated(&self) -> Result<Result<(), ()>, JoinError> {
|
pub async fn ensure_terminated(&self) -> Result<Result<(), ()>, tauri::Error> {
|
||||||
self.command_sender
|
self.command_sender
|
||||||
.send(DownloadManagerSignal::Finish)
|
.send(DownloadManagerSignal::Finish)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|||||||
@ -1,16 +1,11 @@
|
|||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tauri::AppHandle;
|
use tauri::AppHandle;
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState,
|
database::{db::borrow_db_mut_checked, models::data::GameVersion}, error::{library_error::LibraryError, remote_access_error::RemoteAccessError}, games::library::{
|
||||||
database::{db::borrow_db_mut_checked, models::data::GameVersion},
|
|
||||||
error::{library_error::LibraryError, remote_access_error::RemoteAccessError},
|
|
||||||
games::library::{
|
|
||||||
fetch_game_logic_offline, fetch_library_logic_offline, get_current_meta,
|
fetch_game_logic_offline, fetch_library_logic_offline, get_current_meta,
|
||||||
uninstall_game_logic,
|
uninstall_game_logic,
|
||||||
},
|
}, offline, DropFunctionState
|
||||||
offline,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
@ -23,7 +18,7 @@ use super::{
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn fetch_library(
|
pub async fn fetch_library(
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<Vec<Game>, RemoteAccessError> {
|
) -> Result<Vec<Game>, RemoteAccessError> {
|
||||||
offline!(
|
offline!(
|
||||||
state,
|
state,
|
||||||
@ -37,7 +32,7 @@ pub async fn fetch_library(
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn fetch_game(
|
pub async fn fetch_game(
|
||||||
game_id: String,
|
game_id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<FetchGameStruct, RemoteAccessError> {
|
) -> Result<FetchGameStruct, RemoteAccessError> {
|
||||||
offline!(
|
offline!(
|
||||||
state,
|
state,
|
||||||
@ -68,7 +63,7 @@ pub async fn uninstall_game(game_id: String, app_handle: AppHandle) -> Result<()
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn fetch_game_verion_options(
|
pub async fn fetch_game_verion_options(
|
||||||
game_id: String,
|
game_id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<Vec<GameVersion>, RemoteAccessError> {
|
) -> Result<Vec<GameVersion>, RemoteAccessError> {
|
||||||
fetch_game_verion_options_logic(game_id, state).await
|
fetch_game_verion_options_logic(game_id, state).await
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{Arc, Mutex},
|
sync::Arc,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@ -8,8 +8,7 @@ use crate::{
|
|||||||
download_manager::{
|
download_manager::{
|
||||||
download_manager_frontend::DownloadManagerSignal, downloadable::Downloadable,
|
download_manager_frontend::DownloadManagerSignal, downloadable::Downloadable,
|
||||||
},
|
},
|
||||||
error::download_manager_error::DownloadManagerError,
|
error::download_manager_error::DownloadManagerError, DropFunctionState,
|
||||||
AppState,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::download_agent::GameDownloadAgent;
|
use super::download_agent::GameDownloadAgent;
|
||||||
@ -19,9 +18,9 @@ pub async fn download_game(
|
|||||||
game_id: String,
|
game_id: String,
|
||||||
game_version: String,
|
game_version: String,
|
||||||
install_dir: usize,
|
install_dir: usize,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<(), DownloadManagerError<DownloadManagerSignal>> {
|
) -> Result<(), DownloadManagerError<DownloadManagerSignal>> {
|
||||||
let sender = state.lock().unwrap().download_manager.get_sender();
|
let sender = state.lock().await.download_manager.get_sender();
|
||||||
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new_from_index(
|
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new_from_index(
|
||||||
game_id,
|
game_id,
|
||||||
game_version,
|
game_version,
|
||||||
@ -30,7 +29,7 @@ pub async fn download_game(
|
|||||||
).await) as Box<dyn Downloadable + Send + Sync>);
|
).await) as Box<dyn Downloadable + Send + Sync>);
|
||||||
Ok(state
|
Ok(state
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.await
|
||||||
.download_manager
|
.download_manager
|
||||||
.queue_download(game_download_agent)?)
|
.queue_download(game_download_agent)?)
|
||||||
}
|
}
|
||||||
@ -38,7 +37,7 @@ pub async fn download_game(
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn resume_download(
|
pub async fn resume_download(
|
||||||
game_id: String,
|
game_id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<(), DownloadManagerError<DownloadManagerSignal>> {
|
) -> Result<(), DownloadManagerError<DownloadManagerSignal>> {
|
||||||
let s = borrow_db_checked().await
|
let s = borrow_db_checked().await
|
||||||
.applications
|
.applications
|
||||||
@ -56,7 +55,7 @@ pub async fn resume_download(
|
|||||||
install_dir,
|
install_dir,
|
||||||
} => (version_name, install_dir),
|
} => (version_name, install_dir),
|
||||||
};
|
};
|
||||||
let sender = state.lock().unwrap().download_manager.get_sender();
|
let sender = state.lock().await.download_manager.get_sender();
|
||||||
let parent_dir: PathBuf = install_dir.into();
|
let parent_dir: PathBuf = install_dir.into();
|
||||||
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new(
|
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new(
|
||||||
game_id,
|
game_id,
|
||||||
@ -66,7 +65,7 @@ pub async fn resume_download(
|
|||||||
)) as Box<dyn Downloadable + Send + Sync>);
|
)) as Box<dyn Downloadable + Send + Sync>);
|
||||||
Ok(state
|
Ok(state
|
||||||
.lock()
|
.lock()
|
||||||
.unwrap()
|
.await
|
||||||
.download_manager
|
.download_manager
|
||||||
.queue_download(game_download_agent)?)
|
.queue_download(game_download_agent)?)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
|
use crate::DB;
|
||||||
use crate::auth::generate_authorization_header;
|
use crate::auth::generate_authorization_header;
|
||||||
use crate::database::db::{borrow_db_checked, borrow_db_mut_checked};
|
use crate::database::db::{DatabaseImpls, borrow_db_checked, borrow_db_mut_checked};
|
||||||
use crate::database::models::data::{
|
use crate::database::models::data::{
|
||||||
ApplicationTransientStatus, DownloadType, DownloadableMetadata,
|
ApplicationTransientStatus, DownloadType, DownloadableMetadata,
|
||||||
};
|
};
|
||||||
@ -105,6 +106,7 @@ impl GameDownloadAgent {
|
|||||||
|
|
||||||
// Blocking
|
// Blocking
|
||||||
pub async fn download(&self, app_handle: &AppHandle) -> Result<bool, ApplicationDownloadError> {
|
pub async fn download(&self, app_handle: &AppHandle) -> Result<bool, ApplicationDownloadError> {
|
||||||
|
debug!("starting download");
|
||||||
self.setup_download().await?;
|
self.setup_download().await?;
|
||||||
self.set_progress_object_params();
|
self.set_progress_object_params();
|
||||||
let timer = Instant::now();
|
let timer = Instant::now();
|
||||||
@ -268,11 +270,19 @@ impl GameDownloadAgent {
|
|||||||
self.id, max_download_threads
|
self.id, max_download_threads
|
||||||
);
|
);
|
||||||
|
|
||||||
let client = &reqwest::Client::new();
|
let base_url = DB
|
||||||
|
.fetch_base_url()
|
||||||
|
.await
|
||||||
|
.join("/api/v1/client/chunk")
|
||||||
|
.unwrap();
|
||||||
|
let client = reqwest::Client::new();
|
||||||
|
let client_ref = unsafe { extend_lifetime(&client) };
|
||||||
|
|
||||||
let rt = tokio::runtime::Builder::new_multi_thread()
|
let rt = tokio::runtime::Builder::new_multi_thread()
|
||||||
.worker_threads(max_download_threads)
|
.worker_threads(max_download_threads)
|
||||||
.thread_name("drop-download-thread")
|
.thread_name("drop-download-thread")
|
||||||
|
.enable_io()
|
||||||
|
.enable_time()
|
||||||
.build()
|
.build()
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
warn!("failed to create download scheduler: {e}");
|
warn!("failed to create download scheduler: {e}");
|
||||||
@ -288,8 +298,6 @@ impl GameDownloadAgent {
|
|||||||
|
|
||||||
let context_map = self.context_map.lock().unwrap();
|
let context_map = self.context_map.lock().unwrap();
|
||||||
for (index, context) in contexts.iter().enumerate() {
|
for (index, context) in contexts.iter().enumerate() {
|
||||||
let client = client.clone();
|
|
||||||
|
|
||||||
let progress = self.progress.get(index);
|
let progress = self.progress.get(index);
|
||||||
let progress_handle = ProgressHandle::new(progress, self.progress.clone());
|
let progress_handle = ProgressHandle::new(progress, self.progress.clone());
|
||||||
|
|
||||||
@ -308,30 +316,22 @@ impl GameDownloadAgent {
|
|||||||
*/
|
*/
|
||||||
let context = unsafe { extend_lifetime(context) };
|
let context = unsafe { extend_lifetime(context) };
|
||||||
let self_static = unsafe { extend_lifetime(self) };
|
let self_static = unsafe { extend_lifetime(self) };
|
||||||
|
let mut base_url = base_url.clone();
|
||||||
rt.spawn(async move {
|
rt.spawn(async move {
|
||||||
let request = match make_request(
|
{
|
||||||
&client,
|
let mut query = base_url.query_pairs_mut();
|
||||||
&["/api/v1/client/chunk"],
|
let query_params = [
|
||||||
&[
|
|
||||||
("id", &context.game_id),
|
("id", &context.game_id),
|
||||||
("version", &context.version),
|
("version", &context.version),
|
||||||
("name", &context.file_name),
|
("name", &context.file_name),
|
||||||
("chunk", &context.index.to_string()),
|
("chunk", &context.index.to_string()),
|
||||||
],
|
];
|
||||||
async |r| r,
|
for (param, val) in query_params {
|
||||||
)
|
query.append_pair(param.as_ref(), val.as_ref());
|
||||||
.await
|
|
||||||
{
|
|
||||||
Ok(request) => request,
|
|
||||||
Err(e) => {
|
|
||||||
sender
|
|
||||||
.send(DownloadManagerSignal::Error(
|
|
||||||
ApplicationDownloadError::Communication(e),
|
|
||||||
))
|
|
||||||
.unwrap();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
let request = client_ref.get(base_url);
|
||||||
|
|
||||||
match download_game_chunk(
|
match download_game_chunk(
|
||||||
context,
|
context,
|
||||||
@ -356,7 +356,6 @@ impl GameDownloadAgent {
|
|||||||
|
|
||||||
let mut newly_completed = Vec::new();
|
let mut newly_completed = Vec::new();
|
||||||
while let Some(completed_checksum) = rx.recv().await {
|
while let Some(completed_checksum) = rx.recv().await {
|
||||||
println!("completed checksum {}", completed_checksum);
|
|
||||||
newly_completed.push(completed_checksum);
|
newly_completed.push(completed_checksum);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,6 +408,7 @@ impl Downloadable for GameDownloadAgent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async fn download(&self, app_handle: &AppHandle) -> Result<bool, ApplicationDownloadError> {
|
async fn download(&self, app_handle: &AppHandle) -> Result<bool, ApplicationDownloadError> {
|
||||||
|
debug!("starting download from downloadable trait");
|
||||||
*self.status.lock().unwrap() = DownloadStatus::Downloading;
|
*self.status.lock().unwrap() = DownloadStatus::Downloading;
|
||||||
self.download(app_handle).await
|
self.download(app_handle).await
|
||||||
}
|
}
|
||||||
|
|||||||
@ -6,9 +6,9 @@ use crate::error::application_download_error::ApplicationDownloadError;
|
|||||||
use crate::error::drop_server_error::DropServerError;
|
use crate::error::drop_server_error::DropServerError;
|
||||||
use crate::error::remote_access_error::RemoteAccessError;
|
use crate::error::remote_access_error::RemoteAccessError;
|
||||||
use crate::games::downloads::manifest::DropDownloadContext;
|
use crate::games::downloads::manifest::DropDownloadContext;
|
||||||
use crate::remote::auth::generate_authorization_header;
|
use crate::remote::auth::{generate_authorization_header, generate_authorization_header_part};
|
||||||
use futures::TryStreamExt;
|
use futures::TryStreamExt;
|
||||||
use log::{debug, warn};
|
use log::{debug, info, warn};
|
||||||
use md5::{Context, Digest};
|
use md5::{Context, Digest};
|
||||||
use reqwest::RequestBuilder;
|
use reqwest::RequestBuilder;
|
||||||
use tokio::fs::{File, OpenOptions};
|
use tokio::fs::{File, OpenOptions};
|
||||||
@ -97,6 +97,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let mut bytes_read = self.source.read(&mut copy_buf).await?;
|
let mut bytes_read = self.source.read(&mut copy_buf).await?;
|
||||||
|
info!("read {}", bytes_read);
|
||||||
current_size += bytes_read;
|
current_size += bytes_read;
|
||||||
|
|
||||||
if current_size > self.size {
|
if current_size > self.size {
|
||||||
@ -139,8 +140,11 @@ pub async fn download_game_chunk(
|
|||||||
progress.set(0);
|
progress.set(0);
|
||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let header_generator = generate_authorization_header_part().await;
|
||||||
|
|
||||||
let response = request
|
let response = request
|
||||||
.header("Authorization", generate_authorization_header().await)
|
.header("Authorization", header_generator())
|
||||||
.send()
|
.send()
|
||||||
.await
|
.await
|
||||||
.map_err(|e| ApplicationDownloadError::Communication(e.into()))?;
|
.map_err(|e| ApplicationDownloadError::Communication(e.into()))?;
|
||||||
|
|||||||
@ -5,9 +5,7 @@ use serde::{Deserialize, Serialize};
|
|||||||
use tauri::AppHandle;
|
use tauri::AppHandle;
|
||||||
use tauri::Emitter;
|
use tauri::Emitter;
|
||||||
use tokio::spawn;
|
use tokio::spawn;
|
||||||
use tokio::sync::Mutex;
|
|
||||||
|
|
||||||
use crate::AppState;
|
|
||||||
use crate::database::db::{borrow_db_checked, borrow_db_mut_checked};
|
use crate::database::db::{borrow_db_checked, borrow_db_mut_checked};
|
||||||
use crate::database::models::data::{
|
use crate::database::models::data::{
|
||||||
ApplicationTransientStatus, DownloadableMetadata, GameDownloadStatus, GameVersion,
|
ApplicationTransientStatus, DownloadableMetadata, GameDownloadStatus, GameVersion,
|
||||||
@ -18,6 +16,7 @@ use crate::games::state::{GameStatusManager, GameStatusWithTransient};
|
|||||||
use crate::remote::auth::generate_authorization_header;
|
use crate::remote::auth::generate_authorization_header;
|
||||||
use crate::remote::cache::{cache_object, get_cached_object, get_cached_object_db};
|
use crate::remote::cache::{cache_object, get_cached_object, get_cached_object_db};
|
||||||
use crate::remote::requests::make_request;
|
use crate::remote::requests::make_request;
|
||||||
|
use crate::DropFunctionState;
|
||||||
use bitcode::{Decode, Encode};
|
use bitcode::{Decode, Encode};
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
@ -73,7 +72,7 @@ pub struct StatsUpdateEvent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_library_logic(
|
pub async fn fetch_library_logic(
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<Vec<Game>, RemoteAccessError> {
|
) -> Result<Vec<Game>, RemoteAccessError> {
|
||||||
let header = generate_authorization_header().await;
|
let header = generate_authorization_header().await;
|
||||||
|
|
||||||
@ -125,7 +124,7 @@ pub async fn fetch_library_logic(
|
|||||||
Ok(games)
|
Ok(games)
|
||||||
}
|
}
|
||||||
pub async fn fetch_library_logic_offline(
|
pub async fn fetch_library_logic_offline(
|
||||||
_state: tauri::State<'_, Mutex<AppState<'_>>>,
|
_state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<Vec<Game>, RemoteAccessError> {
|
) -> Result<Vec<Game>, RemoteAccessError> {
|
||||||
let mut games: Vec<Game> = get_cached_object("library").await?;
|
let mut games: Vec<Game> = get_cached_object("library").await?;
|
||||||
|
|
||||||
@ -142,7 +141,7 @@ pub async fn fetch_library_logic_offline(
|
|||||||
}
|
}
|
||||||
pub async fn fetch_game_logic(
|
pub async fn fetch_game_logic(
|
||||||
id: String,
|
id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<FetchGameStruct, RemoteAccessError> {
|
) -> Result<FetchGameStruct, RemoteAccessError> {
|
||||||
let mut state_handle = state.lock().await;
|
let mut state_handle = state.lock().await;
|
||||||
|
|
||||||
@ -222,7 +221,7 @@ pub async fn fetch_game_logic(
|
|||||||
|
|
||||||
pub async fn fetch_game_logic_offline(
|
pub async fn fetch_game_logic_offline(
|
||||||
id: String,
|
id: String,
|
||||||
_state: tauri::State<'_, Mutex<AppState<'_>>>,
|
_state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<FetchGameStruct, RemoteAccessError> {
|
) -> Result<FetchGameStruct, RemoteAccessError> {
|
||||||
let handle = borrow_db_checked().await;
|
let handle = borrow_db_checked().await;
|
||||||
let metadata_option = handle.applications.installed_game_version.get(&id);
|
let metadata_option = handle.applications.installed_game_version.get(&id);
|
||||||
@ -253,7 +252,7 @@ pub async fn fetch_game_logic_offline(
|
|||||||
|
|
||||||
pub async fn fetch_game_verion_options_logic(
|
pub async fn fetch_game_verion_options_logic(
|
||||||
game_id: String,
|
game_id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<Vec<GameVersion>, RemoteAccessError> {
|
) -> Result<Vec<GameVersion>, RemoteAccessError> {
|
||||||
let client = reqwest::Client::new();
|
let client = reqwest::Client::new();
|
||||||
|
|
||||||
|
|||||||
@ -72,7 +72,6 @@ use tauri::tray::TrayIconBuilder;
|
|||||||
use tauri::{AppHandle, Manager, RunEvent, WindowEvent};
|
use tauri::{AppHandle, Manager, RunEvent, WindowEvent};
|
||||||
use tauri_plugin_deep_link::DeepLinkExt;
|
use tauri_plugin_deep_link::DeepLinkExt;
|
||||||
use tauri_plugin_dialog::DialogExt;
|
use tauri_plugin_dialog::DialogExt;
|
||||||
use tokio::runtime::Handle;
|
|
||||||
use tokio::sync::Mutex;
|
use tokio::sync::Mutex;
|
||||||
|
|
||||||
#[derive(Clone, Copy, Serialize, Eq, PartialEq)]
|
#[derive(Clone, Copy, Serialize, Eq, PartialEq)]
|
||||||
@ -220,6 +219,7 @@ async fn setup(handle: AppHandle) -> AppState<'static> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub static DB: OnceCellDatabase = OnceCellDatabase::new();
|
pub static DB: OnceCellDatabase = OnceCellDatabase::new();
|
||||||
|
pub type DropFunctionState<'a> = Mutex<AppState<'a>>;
|
||||||
|
|
||||||
pub fn custom_panic_handler(e: &PanicHookInfo) -> Option<()> {
|
pub fn custom_panic_handler(e: &PanicHookInfo) -> Option<()> {
|
||||||
let crash_file = DATA_ROOT_DIR.join(format!(
|
let crash_file = DATA_ROOT_DIR.join(format!(
|
||||||
@ -238,15 +238,12 @@ pub fn custom_panic_handler(e: &PanicHookInfo) -> Option<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub async fn run() {
|
pub fn run() {
|
||||||
panic::set_hook(Box::new(|e| {
|
panic::set_hook(Box::new(|e| {
|
||||||
let _ = custom_panic_handler(e);
|
let _ = custom_panic_handler(e);
|
||||||
println!("{e}");
|
println!("{e}");
|
||||||
}));
|
}));
|
||||||
|
|
||||||
DB.init(async { DatabaseInterface::set_up_database().await })
|
|
||||||
.await;
|
|
||||||
|
|
||||||
let mut builder = tauri::Builder::default()
|
let mut builder = tauri::Builder::default()
|
||||||
.plugin(tauri_plugin_opener::init())
|
.plugin(tauri_plugin_opener::init())
|
||||||
.plugin(tauri_plugin_os::init())
|
.plugin(tauri_plugin_os::init())
|
||||||
@ -318,9 +315,11 @@ pub async fn run() {
|
|||||||
))
|
))
|
||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
let app = app.handle().clone();
|
let app = app.handle().clone();
|
||||||
let runtime = Handle::current();
|
|
||||||
|
|
||||||
runtime.spawn(async move {
|
tauri::async_runtime::spawn(async move {
|
||||||
|
DB.init(async { DatabaseInterface::set_up_database().await })
|
||||||
|
.await;
|
||||||
|
|
||||||
let state = setup(app.clone()).await;
|
let state = setup(app.clone()).await;
|
||||||
info!("initialized drop client");
|
info!("initialized drop client");
|
||||||
if !app.manage(Mutex::new(state)) {
|
if !app.manage(Mutex::new(state)) {
|
||||||
@ -363,18 +362,24 @@ pub async fn run() {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
run_on_tray(|| {
|
let tray_app_handle = app.clone();
|
||||||
|
run_on_tray(move || {
|
||||||
TrayIconBuilder::new()
|
TrayIconBuilder::new()
|
||||||
.icon(app.default_window_icon().unwrap().clone())
|
.icon(tray_app_handle.default_window_icon().unwrap().clone())
|
||||||
.menu(&menu)
|
.menu(&menu)
|
||||||
.on_menu_event(|app, event| {
|
.on_menu_event(|app, event| {
|
||||||
|
let tray_app_handle = app.clone();
|
||||||
tauri::async_runtime::block_on(async move {
|
tauri::async_runtime::block_on(async move {
|
||||||
match event.id.as_ref() {
|
match event.id.as_ref() {
|
||||||
"open" => {
|
"open" => {
|
||||||
app.webview_windows().get("main").unwrap().show().unwrap();
|
app.webview_windows().get("main").unwrap().show().unwrap();
|
||||||
}
|
}
|
||||||
"quit" => {
|
"quit" => {
|
||||||
cleanup_and_exit(app, &app.state()).await;
|
cleanup_and_exit(
|
||||||
|
&tray_app_handle,
|
||||||
|
&tray_app_handle.state(),
|
||||||
|
)
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
_ => {
|
_ => {
|
||||||
@ -383,7 +388,7 @@ pub async fn run() {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.build(&app)
|
.build(&tray_app_handle)
|
||||||
.expect("error while setting up tray menu");
|
.expect("error while setting up tray menu");
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -422,7 +427,7 @@ pub async fn run() {
|
|||||||
})
|
})
|
||||||
.register_asynchronous_uri_scheme_protocol("object", move |ctx, request, responder| {
|
.register_asynchronous_uri_scheme_protocol("object", move |ctx, request, responder| {
|
||||||
tauri::async_runtime::block_on(async move {
|
tauri::async_runtime::block_on(async move {
|
||||||
let state: tauri::State<'_, Mutex<AppState>> = ctx.app_handle().state();
|
let state = ctx.app_handle().state::<DropFunctionState<'_>>();
|
||||||
offline!(
|
offline!(
|
||||||
state,
|
state,
|
||||||
fetch_object,
|
fetch_object,
|
||||||
@ -435,7 +440,7 @@ pub async fn run() {
|
|||||||
})
|
})
|
||||||
.register_asynchronous_uri_scheme_protocol("server", move |ctx, request, responder| {
|
.register_asynchronous_uri_scheme_protocol("server", move |ctx, request, responder| {
|
||||||
tauri::async_runtime::block_on(async move {
|
tauri::async_runtime::block_on(async move {
|
||||||
let state: tauri::State<'_, Mutex<AppState>> = ctx.app_handle().state();
|
let state = ctx.app_handle().state::<DropFunctionState<'_>>();
|
||||||
offline!(
|
offline!(
|
||||||
state,
|
state,
|
||||||
handle_server_proto,
|
handle_server_proto,
|
||||||
|
|||||||
@ -1,7 +1,12 @@
|
|||||||
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
|
||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
#[tokio::main]
|
fn main() {
|
||||||
async fn main() {
|
let global_runtime = tokio::runtime::Builder::new_multi_thread()
|
||||||
drop_app_lib::run().await
|
.worker_threads(32)
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.unwrap();
|
||||||
|
tauri::async_runtime::set(global_runtime.handle().clone());
|
||||||
|
drop_app_lib::run()
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use tokio::sync::Mutex;
|
use crate::{error::process_error::ProcessError, DropFunctionState};
|
||||||
|
|
||||||
use crate::{AppState, error::process_error::ProcessError};
|
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn launch_game(
|
pub async fn launch_game(
|
||||||
id: String,
|
id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<(), ProcessError> {
|
) -> Result<(), ProcessError> {
|
||||||
let state_lock = state.lock().await;
|
let state_lock = state.lock().await;
|
||||||
let mut process_manager_lock = state_lock.process_manager.lock().await;
|
let mut process_manager_lock = state_lock.process_manager.lock().await;
|
||||||
@ -30,7 +28,7 @@ pub async fn launch_game(
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn kill_game(
|
pub async fn kill_game(
|
||||||
game_id: String,
|
game_id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<(), ProcessError> {
|
) -> Result<(), ProcessError> {
|
||||||
let state_lock = state.lock().await;
|
let state_lock = state.lock().await;
|
||||||
let mut process_manager_lock = state_lock.process_manager.lock().await;
|
let mut process_manager_lock = state_lock.process_manager.lock().await;
|
||||||
@ -42,7 +40,7 @@ pub async fn kill_game(
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn open_process_logs(
|
pub async fn open_process_logs(
|
||||||
game_id: String,
|
game_id: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<(), ProcessError> {
|
) -> Result<(), ProcessError> {
|
||||||
let state_lock = state.lock().await;
|
let state_lock = state.lock().await;
|
||||||
let mut process_manager_lock = state_lock.process_manager.lock().await;
|
let mut process_manager_lock = state_lock.process_manager.lock().await;
|
||||||
|
|||||||
@ -16,19 +16,16 @@ use serde::{Deserialize, Serialize};
|
|||||||
use shared_child::SharedChild;
|
use shared_child::SharedChild;
|
||||||
use tauri::{AppHandle, Emitter, Manager};
|
use tauri::{AppHandle, Emitter, Manager};
|
||||||
use tauri_plugin_opener::OpenerExt;
|
use tauri_plugin_opener::OpenerExt;
|
||||||
use tokio::{spawn, sync::Mutex};
|
use tokio::spawn;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, DB,
|
|
||||||
database::{
|
database::{
|
||||||
db::{DATA_ROOT_DIR, borrow_db_mut_checked},
|
db::{borrow_db_mut_checked, DATA_ROOT_DIR},
|
||||||
models::data::{
|
models::data::{
|
||||||
ApplicationTransientStatus, DownloadType, DownloadableMetadata, GameDownloadStatus,
|
ApplicationTransientStatus, DownloadType, DownloadableMetadata, GameDownloadStatus,
|
||||||
GameVersion,
|
GameVersion,
|
||||||
},
|
},
|
||||||
},
|
}, error::process_error::ProcessError, games::{library::push_game_update, state::GameStatusManager}, DropFunctionState, DB
|
||||||
error::process_error::ProcessError,
|
|
||||||
games::{library::push_game_update, state::GameStatusManager},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct RunningProcess {
|
pub struct RunningProcess {
|
||||||
@ -337,7 +334,7 @@ impl ProcessManager<'_> {
|
|||||||
spawn(async move {
|
spawn(async move {
|
||||||
let result: Result<ExitStatus, std::io::Error> = launch_process_handle.wait();
|
let result: Result<ExitStatus, std::io::Error> = launch_process_handle.wait();
|
||||||
|
|
||||||
let app_state = wait_thread_apphandle.state::<Mutex<AppState>>();
|
let app_state = wait_thread_apphandle.state::<tauri::State<'_, DropFunctionState<'_>>>();
|
||||||
let app_state_handle = app_state.lock().await;
|
let app_state_handle = app_state.lock().await;
|
||||||
|
|
||||||
let mut process_manager_handle = app_state_handle.process_manager.lock().await;
|
let mut process_manager_handle = app_state_handle.process_manager.lock().await;
|
||||||
|
|||||||
@ -1,15 +1,15 @@
|
|||||||
use std::{collections::HashMap, env, sync::Mutex};
|
use std::{collections::HashMap, env};
|
||||||
|
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
use droplet_rs::ssl::sign_nonce;
|
use droplet_rs::ssl::sign_nonce;
|
||||||
use gethostname::gethostname;
|
use gethostname::gethostname;
|
||||||
use log::{debug, error, warn};
|
use log::{debug, error, info, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tauri::{AppHandle, Emitter, Manager};
|
use tauri::{AppHandle, Emitter, Manager};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, AppStatus, User,
|
AppStatus, DropFunctionState, User,
|
||||||
database::{
|
database::{
|
||||||
db::{borrow_db_checked, borrow_db_mut_checked},
|
db::{borrow_db_checked, borrow_db_mut_checked},
|
||||||
models::data::DatabaseAuth,
|
models::data::DatabaseAuth,
|
||||||
@ -50,16 +50,23 @@ struct HandshakeResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub async fn generate_authorization_header() -> String {
|
pub async fn generate_authorization_header() -> String {
|
||||||
|
let func = generate_authorization_header_part().await;
|
||||||
|
func()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub async fn generate_authorization_header_part() -> Box<dyn FnOnce() -> String> {
|
||||||
let certs = {
|
let certs = {
|
||||||
let db = borrow_db_checked().await;
|
let db = borrow_db_checked().await;
|
||||||
db.auth.clone().unwrap()
|
db.auth.clone().unwrap()
|
||||||
};
|
};
|
||||||
|
|
||||||
let nonce = Utc::now().timestamp_millis().to_string();
|
Box::new(move || {
|
||||||
|
let nonce = Utc::now().timestamp_millis().to_string();
|
||||||
|
|
||||||
let signature = sign_nonce(certs.private, nonce.clone()).unwrap();
|
let signature = sign_nonce(certs.private, nonce.clone()).unwrap();
|
||||||
|
|
||||||
format!("Nonce {} {} {}", certs.client_id, nonce, signature)
|
format!("Nonce {} {} {}", certs.client_id, nonce, signature)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn fetch_user() -> Result<User, RemoteAccessError> {
|
pub async fn fetch_user() -> Result<User, RemoteAccessError> {
|
||||||
@ -156,11 +163,11 @@ pub async fn recieve_handshake(app: AppHandle, path: String) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let app_state = app.state::<Mutex<AppState>>();
|
let app_state = app.state::<DropFunctionState<'_>>();
|
||||||
|
|
||||||
let (app_status, user) = setup().await;
|
let (app_status, user) = setup().await;
|
||||||
|
|
||||||
let mut state_lock = app_state.lock().unwrap();
|
let mut state_lock = app_state.lock().await;
|
||||||
state_lock.status = app_status;
|
state_lock.status = app_status;
|
||||||
state_lock.user = user;
|
state_lock.user = user;
|
||||||
|
|
||||||
@ -185,20 +192,20 @@ pub async fn auth_initiate_logic() -> Result<(), RemoteAccessError> {
|
|||||||
]),
|
]),
|
||||||
};
|
};
|
||||||
|
|
||||||
let client = reqwest::blocking::Client::new();
|
let client = reqwest::Client::new();
|
||||||
let response = client.post(endpoint.to_string()).json(&body).send()?;
|
let response = client.post(endpoint.to_string()).json(&body).send().await?;
|
||||||
|
|
||||||
if response.status() != 200 {
|
if response.status() != 200 {
|
||||||
let data: DropServerError = response.json()?;
|
let data: DropServerError = response.json().await?;
|
||||||
error!("could not start handshake: {}", data.status_message);
|
error!("could not start handshake: {}", data.status_message);
|
||||||
|
|
||||||
return Err(RemoteAccessError::HandshakeFailed(data.status_message));
|
return Err(RemoteAccessError::HandshakeFailed(data.status_message));
|
||||||
}
|
}
|
||||||
|
|
||||||
let redir_url = response.text()?;
|
let redir_url = response.text().await?;
|
||||||
let complete_redir_url = base_url.join(&redir_url)?;
|
let complete_redir_url = base_url.join(&redir_url)?;
|
||||||
|
|
||||||
debug!("opening web browser to continue authentication");
|
info!("opening web browser to continue authentication: {}", complete_redir_url);
|
||||||
webbrowser::open(complete_redir_url.as_ref()).unwrap();
|
webbrowser::open(complete_redir_url.as_ref()).unwrap();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@ -1,11 +1,10 @@
|
|||||||
use log::debug;
|
use log::debug;
|
||||||
use reqwest::Client;
|
use reqwest::Client;
|
||||||
use tauri::{AppHandle, Emitter, Manager};
|
use tauri::{AppHandle, Emitter, Manager};
|
||||||
use tokio::sync::Mutex;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, AppStatus,
|
AppStatus, DropFunctionState,
|
||||||
database::db::{borrow_db_checked, borrow_db_mut_checked},
|
database::db::{borrow_db_checked, borrow_db_mut_checked},
|
||||||
error::remote_access_error::RemoteAccessError,
|
error::remote_access_error::RemoteAccessError,
|
||||||
remote::{auth::generate_authorization_header, requests::make_request},
|
remote::{auth::generate_authorization_header, requests::make_request},
|
||||||
@ -20,7 +19,7 @@ use super::{
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn use_remote(
|
pub async fn use_remote(
|
||||||
url: String,
|
url: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<(), RemoteAccessError> {
|
) -> Result<(), RemoteAccessError> {
|
||||||
use_remote_logic(url, state).await
|
use_remote_logic(url, state).await
|
||||||
}
|
}
|
||||||
@ -70,7 +69,7 @@ pub async fn sign_out(app: AppHandle) {
|
|||||||
|
|
||||||
// Update app state
|
// Update app state
|
||||||
{
|
{
|
||||||
let app_state = app.state::<Mutex<AppState>>();
|
let app_state = app.state::<DropFunctionState<'_>>();
|
||||||
let mut app_state_handle = app_state.lock().await;
|
let mut app_state_handle = app_state.lock().await;
|
||||||
app_state_handle.status = AppStatus::SignedOut;
|
app_state_handle.status = AppStatus::SignedOut;
|
||||||
app_state_handle.user = None;
|
app_state_handle.user = None;
|
||||||
@ -81,7 +80,7 @@ pub async fn sign_out(app: AppHandle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn retry_connect(state: tauri::State<'_, Mutex<AppState<'_>>>) -> Result<(), ()> {
|
pub async fn retry_connect(state: tauri::State<'_, DropFunctionState<'_>>) -> Result<(), ()> {
|
||||||
let (app_status, user) = setup().await;
|
let (app_status, user) = setup().await;
|
||||||
|
|
||||||
let mut guard = state.lock().await;
|
let mut guard = state.lock().await;
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use http::{uri::PathAndQuery, Request, Response, StatusCode, Uri};
|
use http::{uri::PathAndQuery, Request, Response, StatusCode, Uri};
|
||||||
use reqwest::blocking::Client;
|
use reqwest::Client;
|
||||||
use tauri::UriSchemeResponder;
|
use tauri::UriSchemeResponder;
|
||||||
|
|
||||||
use crate::database::db::borrow_db_checked;
|
use crate::database::db::borrow_db_checked;
|
||||||
@ -44,10 +44,11 @@ pub async fn handle_server_proto(request: Request<Vec<u8>>, responder: UriScheme
|
|||||||
.header("Authorization", format!("Bearer {web_token}"))
|
.header("Authorization", format!("Bearer {web_token}"))
|
||||||
.headers(request.headers().clone())
|
.headers(request.headers().clone())
|
||||||
.send()
|
.send()
|
||||||
|
.await
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let response_status = response.status();
|
let response_status = response.status();
|
||||||
let response_body = response.bytes().unwrap();
|
let response_body = response.bytes().await.unwrap();
|
||||||
|
|
||||||
let http_response = Response::builder()
|
let http_response = Response::builder()
|
||||||
.status(response_status)
|
.status(response_status)
|
||||||
|
|||||||
@ -1,11 +1,9 @@
|
|||||||
use log::{debug, warn};
|
use log::{debug, info, warn};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tokio::sync::Mutex;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
AppState, AppStatus, database::db::borrow_db_mut_checked,
|
database::db::borrow_db_mut_checked, error::remote_access_error::RemoteAccessError, AppStatus, DropFunctionState
|
||||||
error::remote_access_error::RemoteAccessError,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Deserialize)]
|
#[derive(Deserialize)]
|
||||||
@ -16,16 +14,16 @@ struct DropHealthcheck {
|
|||||||
|
|
||||||
pub async fn use_remote_logic(
|
pub async fn use_remote_logic(
|
||||||
url: String,
|
url: String,
|
||||||
state: tauri::State<'_, Mutex<AppState<'_>>>,
|
state: tauri::State<'_, DropFunctionState<'_>>,
|
||||||
) -> Result<(), RemoteAccessError> {
|
) -> Result<(), RemoteAccessError> {
|
||||||
debug!("connecting to url {url}");
|
info!("connecting to url {url}");
|
||||||
let base_url = Url::parse(&url)?;
|
let base_url = Url::parse(&url)?;
|
||||||
|
|
||||||
// Test Drop url
|
// Test Drop url
|
||||||
let test_endpoint = base_url.join("/api/v1")?;
|
let test_endpoint = base_url.join("/api/v1")?;
|
||||||
let response = reqwest::blocking::get(test_endpoint.to_string())?;
|
let response = reqwest::get(test_endpoint.to_string()).await?;
|
||||||
|
|
||||||
let result: DropHealthcheck = response.json()?;
|
let result: DropHealthcheck = response.json().await?;
|
||||||
|
|
||||||
if result.app_name != "Drop" {
|
if result.app_name != "Drop" {
|
||||||
warn!("user entered drop endpoint that connected, but wasn't identified as Drop");
|
warn!("user entered drop endpoint that connected, but wasn't identified as Drop");
|
||||||
|
|||||||
Reference in New Issue
Block a user