chore: commit changes, still bad

This commit is contained in:
DecDuck
2025-07-26 19:56:38 +10:00
parent aad2d964eb
commit 9a85f68d3a
20 changed files with 173 additions and 148 deletions

1
src-tauri/Cargo.lock generated
View File

@ -4337,7 +4337,6 @@ checksum = "cbc931937e6ca3a06e3b6c0aa7841849b160a90351d6ab467a8b9b9959767531"
dependencies = [
"base64 0.22.1",
"bytes",
"futures-channel",
"futures-core",
"futures-util",
"h2 0.4.11",

View File

@ -105,7 +105,7 @@ features = ["other_errors"] # You can also use "yaml_enc"
[dependencies.reqwest]
version = "0.12"
default-features = false
features = ["json", "http2", "blocking", "rustls-tls-webpki-roots", "stream"]
features = ["json", "http2", "rustls-tls-webpki-roots", "stream"]
[dependencies.serde]
version = "1"

View File

@ -1,11 +1,10 @@
use log::{debug, error};
use tauri::AppHandle;
use tokio::sync::Mutex;
use crate::AppState;
use crate::DropFunctionState;
#[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;
Ok(())
@ -13,7 +12,7 @@ pub async fn quit(app: tauri::AppHandle, state: tauri::State<'_, Mutex<AppState<
pub async fn cleanup_and_exit(
app: &AppHandle,
state: &tauri::State<'_, Mutex<AppState<'_>>>,
state: &tauri::State<'_, DropFunctionState<'_>>,
) {
debug!("cleaning up and exiting application");
let download_manager = state.lock().await.download_manager.clone();

View File

@ -1,10 +1,8 @@
use tokio::sync::Mutex;
use crate::AppState;
use crate::DropFunctionState;
#[tauri::command]
pub async fn fetch_state(
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<String, String> {
let guard = state.lock().await;
let cloned_state = serde_json::to_string(&guard.clone()).map_err(|e| e.to_string())?;

View File

@ -1,22 +1,20 @@
use tokio::sync::Mutex;
use crate::{database::models::data::DownloadableMetadata, AppState};
use crate::{database::models::data::DownloadableMetadata, DropFunctionState};
#[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();
Ok(())
}
#[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();
Ok(())
}
#[tauri::command]
pub async fn move_download_in_queue(
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
old_index: usize,
new_index: usize,
) -> Result<(), ()> {
@ -29,7 +27,7 @@ pub async fn move_download_in_queue(
}
#[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);
Ok(())
}

View File

@ -9,7 +9,7 @@ use std::{
use ::futures::future::join_all;
use log::{debug, error, info, warn};
use tauri::{AppHandle, Emitter};
use tokio::{spawn, sync::Mutex, task::JoinHandle};
use tokio::{runtime::Runtime, sync::Mutex};
use crate::{
database::models::data::DownloadableMetadata,
@ -75,9 +75,10 @@ pub struct DownloadManagerBuilder {
progress: CurrentProgressObject,
status: Arc<Mutex<DownloadManagerStatus>>,
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_thread: Mutex<Option<JoinHandle<()>>>,
current_download_thread: Mutex<Option<tokio::task::JoinHandle<()>>>,
active_control_flag: Option<DownloadThreadControl>,
}
impl DownloadManagerBuilder {
@ -95,13 +96,24 @@ impl DownloadManagerBuilder {
sender: command_sender.clone(),
progress: active_progress.clone(),
app_handle,
runtime: tokio::runtime::Builder::new_multi_thread()
.worker_threads(1)
.enable_all()
.build()
.unwrap(),
current_download_agent: None,
current_download_thread: Mutex::new(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)
}
@ -110,7 +122,10 @@ impl DownloadManagerBuilder {
*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();
let download_agent = self.download_agent_registry.remove(meta).unwrap();
self.cleanup_current_download().await;
@ -126,7 +141,6 @@ impl DownloadManagerBuilder {
let mut download_thread_lock = self.current_download_thread.lock().await;
*download_thread_lock = None;
drop(download_thread_lock);
}
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.current_download_agent = Some(download_agent.clone());
info!("fetched control flag");
let sender = self.sender.clone();
info!("cloned sender");
let mut download_thread_lock = self.current_download_thread.lock().await;
info!("acquired download thread lock");
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 {
// Ok(true) is for completed and exited properly
Ok(true) => {
@ -285,6 +307,8 @@ impl DownloadManagerBuilder {
self.set_status(DownloadManagerStatus::Downloading).await;
let active_control_flag = self.active_control_flag.clone().unwrap();
active_control_flag.set(DownloadThreadControlFlag::Go);
// download_thread_lock.take().unwrap().await;
}
async fn manage_stop_signal(&mut self) {
debug!("got signal Stop");
@ -311,7 +335,8 @@ impl DownloadManagerBuilder {
current_agent.on_error(&self.app_handle, &error).await;
self.stop_and_wait_current_download().await;
self.remove_and_cleanup_front_download(&current_agent.metadata()).await;
self.remove_and_cleanup_front_download(&current_agent.metadata())
.await;
}
self.set_status(DownloadManagerStatus::Error).await;
}
@ -365,18 +390,17 @@ impl DownloadManagerBuilder {
}
async fn push_ui_queue_update(&self) {
let queue = &self.download_queue.read();
let queue_objs = join_all(queue
.iter()
.map(async |key| {
let val = self.download_agent_registry.get(key).unwrap();
QueueUpdateEventQueueData {
meta: DownloadableMetadata::clone(key),
status: val.status().await,
progress: val.progress().await.get_progress(),
current: val.progress().await.sum(),
max: val.progress().await.get_max(),
}
})).await;
let queue_objs = join_all(queue.iter().map(async |key| {
let val = self.download_agent_registry.get(key).unwrap();
QueueUpdateEventQueueData {
meta: DownloadableMetadata::clone(key),
status: val.status().await,
progress: val.progress().await.get_progress(),
current: val.progress().await.sum(),
max: val.progress().await.get_max(),
}
}))
.await;
let event_data = QueueUpdateEvent { queue: queue_objs };
self.app_handle.emit("update_queue", event_data).unwrap();

View File

@ -9,7 +9,7 @@ use std::{
use log::{debug, info};
use serde::Serialize;
use tokio::task::{JoinError, JoinHandle};
use tauri::async_runtime::JoinHandle;
use crate::{
database::models::data::DownloadableMetadata,
@ -170,7 +170,7 @@ impl DownloadManager {
pub fn resume_downloads(&self) {
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
.send(DownloadManagerSignal::Finish)
.unwrap();

View File

@ -1,16 +1,11 @@
use serde::Deserialize;
use tauri::AppHandle;
use tokio::sync::Mutex;
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,
uninstall_game_logic,
},
offline,
}, offline, DropFunctionState
};
use super::{
@ -23,7 +18,7 @@ use super::{
#[tauri::command]
pub async fn fetch_library(
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<Vec<Game>, RemoteAccessError> {
offline!(
state,
@ -37,7 +32,7 @@ pub async fn fetch_library(
#[tauri::command]
pub async fn fetch_game(
game_id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<FetchGameStruct, RemoteAccessError> {
offline!(
state,
@ -68,7 +63,7 @@ pub async fn uninstall_game(game_id: String, app_handle: AppHandle) -> Result<()
#[tauri::command]
pub async fn fetch_game_verion_options(
game_id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<Vec<GameVersion>, RemoteAccessError> {
fetch_game_verion_options_logic(game_id, state).await
}

View File

@ -1,6 +1,6 @@
use std::{
path::PathBuf,
sync::{Arc, Mutex},
sync::Arc,
};
use crate::{
@ -8,8 +8,7 @@ use crate::{
download_manager::{
download_manager_frontend::DownloadManagerSignal, downloadable::Downloadable,
},
error::download_manager_error::DownloadManagerError,
AppState,
error::download_manager_error::DownloadManagerError, DropFunctionState,
};
use super::download_agent::GameDownloadAgent;
@ -19,9 +18,9 @@ pub async fn download_game(
game_id: String,
game_version: String,
install_dir: usize,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> 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(
game_id,
game_version,
@ -30,7 +29,7 @@ pub async fn download_game(
).await) as Box<dyn Downloadable + Send + Sync>);
Ok(state
.lock()
.unwrap()
.await
.download_manager
.queue_download(game_download_agent)?)
}
@ -38,7 +37,7 @@ pub async fn download_game(
#[tauri::command]
pub async fn resume_download(
game_id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<(), DownloadManagerError<DownloadManagerSignal>> {
let s = borrow_db_checked().await
.applications
@ -56,7 +55,7 @@ pub async fn resume_download(
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 game_download_agent = Arc::new(Box::new(GameDownloadAgent::new(
game_id,
@ -66,7 +65,7 @@ pub async fn resume_download(
)) as Box<dyn Downloadable + Send + Sync>);
Ok(state
.lock()
.unwrap()
.await
.download_manager
.queue_download(game_download_agent)?)
}

View File

@ -1,5 +1,6 @@
use crate::DB;
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::{
ApplicationTransientStatus, DownloadType, DownloadableMetadata,
};
@ -105,6 +106,7 @@ impl GameDownloadAgent {
// Blocking
pub async fn download(&self, app_handle: &AppHandle) -> Result<bool, ApplicationDownloadError> {
debug!("starting download");
self.setup_download().await?;
self.set_progress_object_params();
let timer = Instant::now();
@ -268,11 +270,19 @@ impl GameDownloadAgent {
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()
.worker_threads(max_download_threads)
.thread_name("drop-download-thread")
.enable_io()
.enable_time()
.build()
.map_err(|e| {
warn!("failed to create download scheduler: {e}");
@ -288,8 +298,6 @@ impl GameDownloadAgent {
let context_map = self.context_map.lock().unwrap();
for (index, context) in contexts.iter().enumerate() {
let client = client.clone();
let progress = self.progress.get(index);
let progress_handle = ProgressHandle::new(progress, self.progress.clone());
@ -308,30 +316,22 @@ impl GameDownloadAgent {
*/
let context = unsafe { extend_lifetime(context) };
let self_static = unsafe { extend_lifetime(self) };
let mut base_url = base_url.clone();
rt.spawn(async move {
let request = match make_request(
&client,
&["/api/v1/client/chunk"],
&[
{
let mut query = base_url.query_pairs_mut();
let query_params = [
("id", &context.game_id),
("version", &context.version),
("name", &context.file_name),
("chunk", &context.index.to_string()),
],
async |r| r,
)
.await
{
Ok(request) => request,
Err(e) => {
sender
.send(DownloadManagerSignal::Error(
ApplicationDownloadError::Communication(e),
))
.unwrap();
return;
];
for (param, val) in query_params {
query.append_pair(param.as_ref(), val.as_ref());
}
};
}
let request = client_ref.get(base_url);
match download_game_chunk(
context,
@ -356,7 +356,6 @@ impl GameDownloadAgent {
let mut newly_completed = Vec::new();
while let Some(completed_checksum) = rx.recv().await {
println!("completed checksum {}", 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> {
debug!("starting download from downloadable trait");
*self.status.lock().unwrap() = DownloadStatus::Downloading;
self.download(app_handle).await
}

View File

@ -6,9 +6,9 @@ use crate::error::application_download_error::ApplicationDownloadError;
use crate::error::drop_server_error::DropServerError;
use crate::error::remote_access_error::RemoteAccessError;
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 log::{debug, warn};
use log::{debug, info, warn};
use md5::{Context, Digest};
use reqwest::RequestBuilder;
use tokio::fs::{File, OpenOptions};
@ -97,6 +97,7 @@ where
}
let mut bytes_read = self.source.read(&mut copy_buf).await?;
info!("read {}", bytes_read);
current_size += bytes_read;
if current_size > self.size {
@ -139,8 +140,11 @@ pub async fn download_game_chunk(
progress.set(0);
return Ok(false);
}
let header_generator = generate_authorization_header_part().await;
let response = request
.header("Authorization", generate_authorization_header().await)
.header("Authorization", header_generator())
.send()
.await
.map_err(|e| ApplicationDownloadError::Communication(e.into()))?;

View File

@ -5,9 +5,7 @@ use serde::{Deserialize, Serialize};
use tauri::AppHandle;
use tauri::Emitter;
use tokio::spawn;
use tokio::sync::Mutex;
use crate::AppState;
use crate::database::db::{borrow_db_checked, borrow_db_mut_checked};
use crate::database::models::data::{
ApplicationTransientStatus, DownloadableMetadata, GameDownloadStatus, GameVersion,
@ -18,6 +16,7 @@ use crate::games::state::{GameStatusManager, GameStatusWithTransient};
use crate::remote::auth::generate_authorization_header;
use crate::remote::cache::{cache_object, get_cached_object, get_cached_object_db};
use crate::remote::requests::make_request;
use crate::DropFunctionState;
use bitcode::{Decode, Encode};
#[derive(Serialize, Deserialize, Debug)]
@ -73,7 +72,7 @@ pub struct StatsUpdateEvent {
}
pub async fn fetch_library_logic(
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<Vec<Game>, RemoteAccessError> {
let header = generate_authorization_header().await;
@ -125,7 +124,7 @@ pub async fn fetch_library_logic(
Ok(games)
}
pub async fn fetch_library_logic_offline(
_state: tauri::State<'_, Mutex<AppState<'_>>>,
_state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<Vec<Game>, RemoteAccessError> {
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(
id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<FetchGameStruct, RemoteAccessError> {
let mut state_handle = state.lock().await;
@ -222,7 +221,7 @@ pub async fn fetch_game_logic(
pub async fn fetch_game_logic_offline(
id: String,
_state: tauri::State<'_, Mutex<AppState<'_>>>,
_state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<FetchGameStruct, RemoteAccessError> {
let handle = borrow_db_checked().await;
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(
game_id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<Vec<GameVersion>, RemoteAccessError> {
let client = reqwest::Client::new();

View File

@ -72,7 +72,6 @@ use tauri::tray::TrayIconBuilder;
use tauri::{AppHandle, Manager, RunEvent, WindowEvent};
use tauri_plugin_deep_link::DeepLinkExt;
use tauri_plugin_dialog::DialogExt;
use tokio::runtime::Handle;
use tokio::sync::Mutex;
#[derive(Clone, Copy, Serialize, Eq, PartialEq)]
@ -220,6 +219,7 @@ async fn setup(handle: AppHandle) -> AppState<'static> {
}
pub static DB: OnceCellDatabase = OnceCellDatabase::new();
pub type DropFunctionState<'a> = Mutex<AppState<'a>>;
pub fn custom_panic_handler(e: &PanicHookInfo) -> Option<()> {
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)]
pub async fn run() {
pub fn run() {
panic::set_hook(Box::new(|e| {
let _ = custom_panic_handler(e);
println!("{e}");
}));
DB.init(async { DatabaseInterface::set_up_database().await })
.await;
let mut builder = tauri::Builder::default()
.plugin(tauri_plugin_opener::init())
.plugin(tauri_plugin_os::init())
@ -318,9 +315,11 @@ pub async fn run() {
))
.setup(|app| {
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;
info!("initialized drop client");
if !app.manage(Mutex::new(state)) {
@ -363,18 +362,24 @@ pub async fn run() {
)
.unwrap();
run_on_tray(|| {
let tray_app_handle = app.clone();
run_on_tray(move || {
TrayIconBuilder::new()
.icon(app.default_window_icon().unwrap().clone())
.icon(tray_app_handle.default_window_icon().unwrap().clone())
.menu(&menu)
.on_menu_event(|app, event| {
let tray_app_handle = app.clone();
tauri::async_runtime::block_on(async move {
match event.id.as_ref() {
"open" => {
app.webview_windows().get("main").unwrap().show().unwrap();
}
"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");
});
@ -422,7 +427,7 @@ pub async fn run() {
})
.register_asynchronous_uri_scheme_protocol("object", move |ctx, request, responder| {
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!(
state,
fetch_object,
@ -435,7 +440,7 @@ pub async fn run() {
})
.register_asynchronous_uri_scheme_protocol("server", move |ctx, request, responder| {
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!(
state,
handle_server_proto,

View File

@ -1,7 +1,12 @@
// Prevents additional console window on Windows in release, DO NOT REMOVE!!
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
#[tokio::main]
async fn main() {
drop_app_lib::run().await
fn main() {
let global_runtime = tokio::runtime::Builder::new_multi_thread()
.worker_threads(32)
.enable_all()
.build()
.unwrap();
tauri::async_runtime::set(global_runtime.handle().clone());
drop_app_lib::run()
}

View File

@ -1,11 +1,9 @@
use tokio::sync::Mutex;
use crate::{AppState, error::process_error::ProcessError};
use crate::{error::process_error::ProcessError, DropFunctionState};
#[tauri::command]
pub async fn launch_game(
id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<(), ProcessError> {
let state_lock = state.lock().await;
let mut process_manager_lock = state_lock.process_manager.lock().await;
@ -30,7 +28,7 @@ pub async fn launch_game(
#[tauri::command]
pub async fn kill_game(
game_id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<(), ProcessError> {
let state_lock = state.lock().await;
let mut process_manager_lock = state_lock.process_manager.lock().await;
@ -42,7 +40,7 @@ pub async fn kill_game(
#[tauri::command]
pub async fn open_process_logs(
game_id: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<(), ProcessError> {
let state_lock = state.lock().await;
let mut process_manager_lock = state_lock.process_manager.lock().await;

View File

@ -16,19 +16,16 @@ use serde::{Deserialize, Serialize};
use shared_child::SharedChild;
use tauri::{AppHandle, Emitter, Manager};
use tauri_plugin_opener::OpenerExt;
use tokio::{spawn, sync::Mutex};
use tokio::spawn;
use crate::{
AppState, DB,
database::{
db::{DATA_ROOT_DIR, borrow_db_mut_checked},
db::{borrow_db_mut_checked, DATA_ROOT_DIR},
models::data::{
ApplicationTransientStatus, DownloadType, DownloadableMetadata, GameDownloadStatus,
GameVersion,
},
},
error::process_error::ProcessError,
games::{library::push_game_update, state::GameStatusManager},
}, error::process_error::ProcessError, games::{library::push_game_update, state::GameStatusManager}, DropFunctionState, DB
};
pub struct RunningProcess {
@ -337,7 +334,7 @@ impl ProcessManager<'_> {
spawn(async move {
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 mut process_manager_handle = app_state_handle.process_manager.lock().await;

View File

@ -1,15 +1,15 @@
use std::{collections::HashMap, env, sync::Mutex};
use std::{collections::HashMap, env};
use chrono::Utc;
use droplet_rs::ssl::sign_nonce;
use gethostname::gethostname;
use log::{debug, error, warn};
use log::{debug, error, info, warn};
use serde::{Deserialize, Serialize};
use tauri::{AppHandle, Emitter, Manager};
use url::Url;
use crate::{
AppState, AppStatus, User,
AppStatus, DropFunctionState, User,
database::{
db::{borrow_db_checked, borrow_db_mut_checked},
models::data::DatabaseAuth,
@ -50,16 +50,23 @@ struct HandshakeResponse {
}
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 db = borrow_db_checked().await;
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> {
@ -156,11 +163,11 @@ pub async fn recieve_handshake(app: AppHandle, path: String) {
return;
}
let app_state = app.state::<Mutex<AppState>>();
let app_state = app.state::<DropFunctionState<'_>>();
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.user = user;
@ -185,20 +192,20 @@ pub async fn auth_initiate_logic() -> Result<(), RemoteAccessError> {
]),
};
let client = reqwest::blocking::Client::new();
let response = client.post(endpoint.to_string()).json(&body).send()?;
let client = reqwest::Client::new();
let response = client.post(endpoint.to_string()).json(&body).send().await?;
if response.status() != 200 {
let data: DropServerError = response.json()?;
let data: DropServerError = response.json().await?;
error!("could not start handshake: {}", 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)?;
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();
Ok(())

View File

@ -1,11 +1,10 @@
use log::debug;
use reqwest::Client;
use tauri::{AppHandle, Emitter, Manager};
use tokio::sync::Mutex;
use url::Url;
use crate::{
AppState, AppStatus,
AppStatus, DropFunctionState,
database::db::{borrow_db_checked, borrow_db_mut_checked},
error::remote_access_error::RemoteAccessError,
remote::{auth::generate_authorization_header, requests::make_request},
@ -20,7 +19,7 @@ use super::{
#[tauri::command]
pub async fn use_remote(
url: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<(), RemoteAccessError> {
use_remote_logic(url, state).await
}
@ -70,7 +69,7 @@ pub async fn sign_out(app: AppHandle) {
// 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;
app_state_handle.status = AppStatus::SignedOut;
app_state_handle.user = None;
@ -81,7 +80,7 @@ pub async fn sign_out(app: AppHandle) {
}
#[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 mut guard = state.lock().await;

View File

@ -1,7 +1,7 @@
use std::str::FromStr;
use http::{uri::PathAndQuery, Request, Response, StatusCode, Uri};
use reqwest::blocking::Client;
use reqwest::Client;
use tauri::UriSchemeResponder;
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}"))
.headers(request.headers().clone())
.send()
.await
.unwrap();
let response_status = response.status();
let response_body = response.bytes().unwrap();
let response_body = response.bytes().await.unwrap();
let http_response = Response::builder()
.status(response_status)

View File

@ -1,11 +1,9 @@
use log::{debug, warn};
use log::{debug, info, warn};
use serde::Deserialize;
use tokio::sync::Mutex;
use url::Url;
use crate::{
AppState, AppStatus, database::db::borrow_db_mut_checked,
error::remote_access_error::RemoteAccessError,
database::db::borrow_db_mut_checked, error::remote_access_error::RemoteAccessError, AppStatus, DropFunctionState
};
#[derive(Deserialize)]
@ -16,16 +14,16 @@ struct DropHealthcheck {
pub async fn use_remote_logic(
url: String,
state: tauri::State<'_, Mutex<AppState<'_>>>,
state: tauri::State<'_, DropFunctionState<'_>>,
) -> Result<(), RemoteAccessError> {
debug!("connecting to url {url}");
info!("connecting to url {url}");
let base_url = Url::parse(&url)?;
// Test Drop url
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" {
warn!("user entered drop endpoint that connected, but wasn't identified as Drop");