mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-10 04:22:13 +10:00
Merge branch 'compat' into develop
Signed-off-by: quexeky <git@quexeky.dev>
This commit is contained in:
3
.gitmodules
vendored
3
.gitmodules
vendored
@ -4,3 +4,6 @@
|
|||||||
[submodule "src-tauri/tailscale/libtailscale"]
|
[submodule "src-tauri/tailscale/libtailscale"]
|
||||||
path = src-tauri/tailscale/libtailscale
|
path = src-tauri/tailscale/libtailscale
|
||||||
url = https://github.com/tailscale/libtailscale.git
|
url = https://github.com/tailscale/libtailscale.git
|
||||||
|
[submodule "src-tauri/umu/umu-launcher"]
|
||||||
|
path = src-tauri/umu/umu-launcher
|
||||||
|
url = https://github.com/Open-Wine-Components/umu-launcher.git
|
||||||
|
|||||||
43
src-tauri/Cargo.lock
generated
43
src-tauri/Cargo.lock
generated
@ -1332,6 +1332,7 @@ dependencies = [
|
|||||||
"log",
|
"log",
|
||||||
"log4rs",
|
"log4rs",
|
||||||
"md5",
|
"md5",
|
||||||
|
"memfd-exec",
|
||||||
"native_model",
|
"native_model",
|
||||||
"parking_lot 0.12.3",
|
"parking_lot 0.12.3",
|
||||||
"rayon",
|
"rayon",
|
||||||
@ -1571,7 +1572,7 @@ version = "0.3.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
|
checksum = "38e2275cc4e4fc009b0669731a1e5ab7ebf11f469eaede2bab9309a5b4d6057f"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memoffset",
|
"memoffset 0.9.1",
|
||||||
"rustc_version",
|
"rustc_version",
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -2948,6 +2949,16 @@ version = "2.7.4"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memfd-exec"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e627eb44f3789e87dccac3f4c7279a608cbf14ff71f2c54f122f44a07e2ca338"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
"nix 0.26.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memmap"
|
name = "memmap"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
@ -2967,6 +2978,15 @@ dependencies = [
|
|||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "memoffset"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||||
|
dependencies = [
|
||||||
|
"autocfg",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "memoffset"
|
name = "memoffset"
|
||||||
version = "0.9.1"
|
version = "0.9.1"
|
||||||
@ -3126,6 +3146,19 @@ version = "1.0.6"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
checksum = "650eef8c711430f1a879fdd01d4745a7deea475becfb90269c06775983bbf086"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "nix"
|
||||||
|
version = "0.26.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 1.3.2",
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"memoffset 0.7.1",
|
||||||
|
"pin-utils",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nix"
|
name = "nix"
|
||||||
version = "0.30.1"
|
version = "0.30.1"
|
||||||
@ -3136,7 +3169,7 @@ dependencies = [
|
|||||||
"cfg-if",
|
"cfg-if",
|
||||||
"cfg_aliases",
|
"cfg_aliases",
|
||||||
"libc",
|
"libc",
|
||||||
"memoffset",
|
"memoffset 0.9.1",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -4032,7 +4065,7 @@ dependencies = [
|
|||||||
"once_cell",
|
"once_cell",
|
||||||
"socket2",
|
"socket2",
|
||||||
"tracing",
|
"tracing",
|
||||||
"windows-sys 0.52.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
@ -6152,7 +6185,7 @@ version = "1.1.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
|
checksum = "89daebc3e6fd160ac4aa9fc8b3bf71e1f74fbf92367ae71fb83a037e8bf164b9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"memoffset",
|
"memoffset 0.9.1",
|
||||||
"tempfile",
|
"tempfile",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
@ -7314,7 +7347,7 @@ dependencies = [
|
|||||||
"futures-core",
|
"futures-core",
|
||||||
"futures-lite",
|
"futures-lite",
|
||||||
"hex 0.4.3",
|
"hex 0.4.3",
|
||||||
"nix",
|
"nix 0.30.1",
|
||||||
"ordered-stream",
|
"ordered-stream",
|
||||||
"serde",
|
"serde",
|
||||||
"serde_repr",
|
"serde_repr",
|
||||||
|
|||||||
@ -57,6 +57,7 @@ droplet-rs = "0.7.3"
|
|||||||
gethostname = "1.0.1"
|
gethostname = "1.0.1"
|
||||||
native_model = { version = "0.6.1", features = ["rmp_serde_1_3"] }
|
native_model = { version = "0.6.1", features = ["rmp_serde_1_3"] }
|
||||||
tailscale = { path = "./tailscale" }
|
tailscale = { path = "./tailscale" }
|
||||||
|
memfd-exec = "0.2.1"
|
||||||
|
|
||||||
[dependencies.dynfmt]
|
[dependencies.dynfmt]
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
|||||||
3
src-tauri/src/client/mod.rs
Normal file
3
src-tauri/src/client/mod.rs
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
pub mod autostart;
|
||||||
|
pub mod cleanup;
|
||||||
|
pub mod commands;
|
||||||
@ -6,14 +6,12 @@ use std::{
|
|||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::{
|
use crate::{database::db::borrow_db_mut_checked, error::download_manager_error::DownloadManagerError};
|
||||||
database::{db::borrow_db_mut_checked},
|
|
||||||
download_manager::internal_error::InternalError,
|
|
||||||
};
|
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
db::{borrow_db_checked, save_db, DATA_ROOT_DIR},
|
db::{borrow_db_checked, save_db, DATA_ROOT_DIR},
|
||||||
debug::SystemData, models::data::Settings,
|
debug::SystemData,
|
||||||
|
models::data::Settings,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Will, in future, return disk/remaining size
|
// Will, in future, return disk/remaining size
|
||||||
@ -33,7 +31,7 @@ pub fn delete_download_dir(index: usize) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn add_download_dir(new_dir: PathBuf) -> Result<(), InternalError<()>> {
|
pub fn add_download_dir(new_dir: PathBuf) -> Result<(), DownloadManagerError<()>> {
|
||||||
// Check the new directory is all good
|
// Check the new directory is all good
|
||||||
let new_dir_path = Path::new(&new_dir);
|
let new_dir_path = Path::new(&new_dir);
|
||||||
if new_dir_path.exists() {
|
if new_dir_path.exists() {
|
||||||
|
|||||||
@ -1,8 +1,6 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
|
||||||
fs::{self, create_dir_all},
|
fs::{self, create_dir_all},
|
||||||
hash::Hash,
|
path::PathBuf,
|
||||||
path::{Path, PathBuf},
|
|
||||||
sync::{LazyLock, Mutex, RwLockReadGuard, RwLockWriteGuard},
|
sync::{LazyLock, Mutex, RwLockReadGuard, RwLockWriteGuard},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -10,14 +8,12 @@ use chrono::Utc;
|
|||||||
use directories::BaseDirs;
|
use directories::BaseDirs;
|
||||||
use log::{debug, error, info};
|
use log::{debug, error, info};
|
||||||
use rustbreak::{DeSerError, DeSerializer, PathDatabase, RustbreakError};
|
use rustbreak::{DeSerError, DeSerializer, PathDatabase, RustbreakError};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Serialize};
|
||||||
use serde_with::serde_as;
|
|
||||||
use tauri::AppHandle;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::DB;
|
use crate::DB;
|
||||||
|
|
||||||
use super::models::data::{Database, GameVersion};
|
use super::models::data::Database;
|
||||||
|
|
||||||
pub static DATA_ROOT_DIR: LazyLock<Mutex<PathBuf>> =
|
pub static DATA_ROOT_DIR: LazyLock<Mutex<PathBuf>> =
|
||||||
LazyLock::new(|| Mutex::new(BaseDirs::new().unwrap().data_dir().join("drop")));
|
LazyLock::new(|| Mutex::new(BaseDirs::new().unwrap().data_dir().join("drop")));
|
||||||
@ -58,12 +54,14 @@ impl DatabaseImpls for DatabaseInterface {
|
|||||||
let games_base_dir = data_root_dir.join("games");
|
let games_base_dir = data_root_dir.join("games");
|
||||||
let logs_root_dir = data_root_dir.join("logs");
|
let logs_root_dir = data_root_dir.join("logs");
|
||||||
let cache_dir = data_root_dir.join("cache");
|
let cache_dir = data_root_dir.join("cache");
|
||||||
|
let pfx_dir = data_root_dir.join("pfx");
|
||||||
|
|
||||||
debug!("creating data directory at {:?}", data_root_dir);
|
debug!("creating data directory at {:?}", data_root_dir);
|
||||||
create_dir_all(data_root_dir.clone()).unwrap();
|
create_dir_all(data_root_dir.clone()).unwrap();
|
||||||
create_dir_all(&games_base_dir).unwrap();
|
create_dir_all(&games_base_dir).unwrap();
|
||||||
create_dir_all(&logs_root_dir).unwrap();
|
create_dir_all(&logs_root_dir).unwrap();
|
||||||
create_dir_all(&cache_dir).unwrap();
|
create_dir_all(&cache_dir).unwrap();
|
||||||
|
create_dir_all(&pfx_dir).unwrap();
|
||||||
|
|
||||||
let exists = fs::exists(db_path.clone()).unwrap();
|
let exists = fs::exists(db_path.clone()).unwrap();
|
||||||
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod db;
|
pub mod db;
|
||||||
pub mod debug;
|
pub mod debug;
|
||||||
pub mod models;
|
pub mod models;
|
||||||
|
|||||||
@ -3,7 +3,7 @@ pub mod data {
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub type GameVersion = v1::GameVersion;
|
pub type GameVersion = v1::GameVersion;
|
||||||
pub type Database = v1::Database;
|
pub type Database = v2::Database;
|
||||||
pub type Settings = v1::Settings;
|
pub type Settings = v1::Settings;
|
||||||
pub type DatabaseAuth = v1::DatabaseAuth;
|
pub type DatabaseAuth = v1::DatabaseAuth;
|
||||||
|
|
||||||
@ -11,6 +11,8 @@ pub mod data {
|
|||||||
pub type ApplicationTransientStatus = v1::ApplicationTransientStatus;
|
pub type ApplicationTransientStatus = v1::ApplicationTransientStatus;
|
||||||
pub type DownloadableMetadata = v1::DownloadableMetadata;
|
pub type DownloadableMetadata = v1::DownloadableMetadata;
|
||||||
pub type DownloadType = v1::DownloadType;
|
pub type DownloadType = v1::DownloadType;
|
||||||
|
pub type DatabaseApplications = v1::DatabaseApplications;
|
||||||
|
pub type DatabaseCompatInfo = v2::DatabaseCompatInfo;
|
||||||
|
|
||||||
pub mod v1 {
|
pub mod v1 {
|
||||||
use crate::process::process_manager::Platform;
|
use crate::process::process_manager::Platform;
|
||||||
@ -157,8 +159,46 @@ pub mod data {
|
|||||||
pub prev_database: Option<PathBuf>,
|
pub prev_database: Option<PathBuf>,
|
||||||
pub cache_dir: PathBuf,
|
pub cache_dir: PathBuf,
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub mod v2 {
|
||||||
|
use std::{collections::HashMap, path::PathBuf, process::Command};
|
||||||
|
|
||||||
|
use crate::process::process_manager::UMU_LAUNCHER_EXECUTABLE;
|
||||||
|
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[native_model(id = 1, version = 2)]
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Default)]
|
||||||
|
pub struct Database {
|
||||||
|
#[serde(default)]
|
||||||
|
pub settings: Settings,
|
||||||
|
pub auth: Option<DatabaseAuth>,
|
||||||
|
pub base_url: String,
|
||||||
|
pub applications: DatabaseApplications,
|
||||||
|
pub prev_database: Option<PathBuf>,
|
||||||
|
pub cache_dir: PathBuf,
|
||||||
|
pub compat_info: Option<DatabaseCompatInfo>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[native_model(id = 8, version = 2)]
|
||||||
|
#[derive(Serialize, Deserialize, Clone, Default)]
|
||||||
|
|
||||||
|
pub struct DatabaseCompatInfo {
|
||||||
|
umu_installed: bool,
|
||||||
|
}
|
||||||
|
|
||||||
impl Database {
|
impl Database {
|
||||||
|
fn create_new_compat_info() -> Option<DatabaseCompatInfo> {
|
||||||
|
#[cfg(target_os = "windows")]
|
||||||
|
return None;
|
||||||
|
|
||||||
|
let has_umu_installed = Command::new(UMU_LAUNCHER_EXECUTABLE).spawn().is_ok();
|
||||||
|
Some(DatabaseCompatInfo {
|
||||||
|
umu_installed: has_umu_installed,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
pub fn new<T: Into<PathBuf>>(
|
pub fn new<T: Into<PathBuf>>(
|
||||||
games_base_dir: T,
|
games_base_dir: T,
|
||||||
prev_database: Option<PathBuf>,
|
prev_database: Option<PathBuf>,
|
||||||
@ -177,6 +217,21 @@ pub mod data {
|
|||||||
auth: None,
|
auth: None,
|
||||||
settings: Settings::default(),
|
settings: Settings::default(),
|
||||||
cache_dir,
|
cache_dir,
|
||||||
|
compat_info: Database::create_new_compat_info(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<v1::Database> for Database {
|
||||||
|
fn from(value: v1::Database) -> Self {
|
||||||
|
Self {
|
||||||
|
settings: value.settings,
|
||||||
|
auth: value.auth,
|
||||||
|
base_url: value.base_url,
|
||||||
|
applications: value.applications,
|
||||||
|
prev_database: value.prev_database,
|
||||||
|
cache_dir: value.cache_dir,
|
||||||
|
compat_info: Database::create_new_compat_info(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -12,11 +12,13 @@ use std::{
|
|||||||
use log::{debug, info};
|
use log::{debug, info};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
|
|
||||||
use crate::{database::models::data::DownloadableMetadata, error::application_download_error::ApplicationDownloadError};
|
use crate::{
|
||||||
|
database::models::data::DownloadableMetadata,
|
||||||
|
error::application_download_error::ApplicationDownloadError,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
download_manager_builder::{CurrentProgressObject, DownloadAgent},
|
download_manager_builder::{CurrentProgressObject, DownloadAgent}, util::queue::Queue,
|
||||||
queue::Queue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub enum DownloadManagerSignal {
|
pub enum DownloadManagerSignal {
|
||||||
|
|||||||
@ -11,15 +11,14 @@ use log::{debug, error, info, warn};
|
|||||||
use tauri::{AppHandle, Emitter};
|
use tauri::{AppHandle, Emitter};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::models::data::DownloadableMetadata, error::application_download_error::ApplicationDownloadError, games::library::{QueueUpdateEvent, QueueUpdateEventQueueData, StatsUpdateEvent}
|
database::models::data::DownloadableMetadata,
|
||||||
|
error::application_download_error::ApplicationDownloadError,
|
||||||
|
games::library::{QueueUpdateEvent, QueueUpdateEventQueueData, StatsUpdateEvent},
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
download_manager::{DownloadManager, DownloadManagerSignal, DownloadManagerStatus},
|
download_manager::{DownloadManager, DownloadManagerSignal, DownloadManagerStatus},
|
||||||
download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag},
|
downloadable::Downloadable, util::{download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag}, progress_object::ProgressObject, queue::Queue},
|
||||||
downloadable::Downloadable,
|
|
||||||
progress_object::ProgressObject,
|
|
||||||
queue::Queue,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub type DownloadAgent = Arc<Box<dyn Downloadable + Send + Sync>>;
|
pub type DownloadAgent = Arc<Box<dyn Downloadable + Send + Sync>>;
|
||||||
|
|||||||
@ -2,11 +2,13 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use tauri::AppHandle;
|
use tauri::AppHandle;
|
||||||
|
|
||||||
use crate::{database::models::data::DownloadableMetadata, error::application_download_error::ApplicationDownloadError};
|
use crate::{
|
||||||
|
database::models::data::DownloadableMetadata,
|
||||||
|
error::application_download_error::ApplicationDownloadError,
|
||||||
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
download_manager::DownloadStatus, download_thread_control_flag::DownloadThreadControl,
|
download_manager::DownloadStatus, util::{download_thread_control_flag::DownloadThreadControl, progress_object::ProgressObject},
|
||||||
progress_object::ProgressObject,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Downloadable: Send + Sync {
|
pub trait Downloadable: Send + Sync {
|
||||||
|
|||||||
@ -1 +0,0 @@
|
|||||||
use serde::{Deserialize, Serialize};
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
use std::{fmt::Display, io, sync::mpsc::SendError};
|
|
||||||
|
|
||||||
use serde_with::SerializeDisplay;
|
|
||||||
|
|
||||||
#[derive(SerializeDisplay)]
|
|
||||||
pub enum InternalError<T> {
|
|
||||||
IOError(io::Error),
|
|
||||||
SignalError(SendError<T>),
|
|
||||||
}
|
|
||||||
impl<T> Display for InternalError<T> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
match self {
|
|
||||||
InternalError::IOError(error) => write!(f, "{}", error),
|
|
||||||
InternalError::SignalError(send_error) => write!(f, "{}", send_error),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> From<SendError<T>> for InternalError<T> {
|
|
||||||
fn from(value: SendError<T>) -> Self {
|
|
||||||
InternalError::SignalError(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<T> From<io::Error> for InternalError<T> {
|
|
||||||
fn from(value: io::Error) -> Self {
|
|
||||||
InternalError::IOError(value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,10 +1,5 @@
|
|||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod download_manager;
|
pub mod download_manager;
|
||||||
pub mod download_manager_builder;
|
pub mod download_manager_builder;
|
||||||
pub mod download_thread_control_flag;
|
|
||||||
pub mod downloadable;
|
pub mod downloadable;
|
||||||
pub mod downloadable_metadata;
|
pub mod util;
|
||||||
pub mod internal_error;
|
|
||||||
pub mod progress_object;
|
|
||||||
pub mod queue;
|
|
||||||
pub mod rolling_progress_updates;
|
|
||||||
4
src-tauri/src/download_manager/util/mod.rs
Normal file
4
src-tauri/src/download_manager/util/mod.rs
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
pub mod progress_object;
|
||||||
|
pub mod queue;
|
||||||
|
pub mod rolling_progress_updates;
|
||||||
|
pub mod download_thread_control_flag;
|
||||||
@ -10,8 +10,10 @@ use std::{
|
|||||||
use atomic_instant_full::AtomicInstant;
|
use atomic_instant_full::AtomicInstant;
|
||||||
use throttle_my_fn::throttle;
|
use throttle_my_fn::throttle;
|
||||||
|
|
||||||
|
use crate::download_manager::download_manager::DownloadManagerSignal;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
download_manager::DownloadManagerSignal, rolling_progress_updates::RollingProgressWindow,
|
rolling_progress_updates::RollingProgressWindow,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
27
src-tauri/src/error/download_manager_error.rs
Normal file
27
src-tauri/src/error/download_manager_error.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
use std::{fmt::Display, io, sync::mpsc::SendError};
|
||||||
|
|
||||||
|
use serde_with::SerializeDisplay;
|
||||||
|
|
||||||
|
#[derive(SerializeDisplay)]
|
||||||
|
pub enum DownloadManagerError<T> {
|
||||||
|
IOError(io::Error),
|
||||||
|
SignalError(SendError<T>),
|
||||||
|
}
|
||||||
|
impl<T> Display for DownloadManagerError<T> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
match self {
|
||||||
|
DownloadManagerError::IOError(error) => write!(f, "{}", error),
|
||||||
|
DownloadManagerError::SignalError(send_error) => write!(f, "{}", send_error),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T> From<SendError<T>> for DownloadManagerError<T> {
|
||||||
|
fn from(value: SendError<T>) -> Self {
|
||||||
|
DownloadManagerError::SignalError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<T> From<io::Error> for DownloadManagerError<T> {
|
||||||
|
fn from(value: io::Error) -> Self {
|
||||||
|
DownloadManagerError::IOError(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,5 +1,6 @@
|
|||||||
pub mod application_download_error;
|
pub mod application_download_error;
|
||||||
pub mod drop_server_error;
|
pub mod drop_server_error;
|
||||||
|
pub mod download_manager_error;
|
||||||
pub mod library_error;
|
pub mod library_error;
|
||||||
pub mod process_error;
|
pub mod process_error;
|
||||||
pub mod remote_access_error;
|
pub mod remote_access_error;
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
use std::{
|
use std::{
|
||||||
any::{Any, TypeId},
|
|
||||||
error::Error,
|
error::Error,
|
||||||
fmt::{Display, Formatter},
|
fmt::{Display, Formatter},
|
||||||
sync::Arc,
|
sync::Arc,
|
||||||
@ -23,7 +22,6 @@ pub enum RemoteAccessError {
|
|||||||
ManifestDownloadFailed(StatusCode, String),
|
ManifestDownloadFailed(StatusCode, String),
|
||||||
OutOfSync,
|
OutOfSync,
|
||||||
Cache(cacache::Error),
|
Cache(cacache::Error),
|
||||||
Generic(String),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for RemoteAccessError {
|
impl Display for RemoteAccessError {
|
||||||
@ -59,7 +57,6 @@ impl Display for RemoteAccessError {
|
|||||||
status, response
|
status, response
|
||||||
),
|
),
|
||||||
RemoteAccessError::OutOfSync => write!(f, "server's and client's time are out of sync. Please ensure they are within at least 30 seconds of each other"),
|
RemoteAccessError::OutOfSync => write!(f, "server's and client's time are out of sync. Please ensure they are within at least 30 seconds of each other"),
|
||||||
RemoteAccessError::Generic(message) => write!(f, "{}", message),
|
|
||||||
RemoteAccessError::Cache(error) => write!(f, "Cache Error: {}", error),
|
RemoteAccessError::Cache(error) => write!(f, "Cache Error: {}", error),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -11,7 +11,7 @@ pub struct Collection {
|
|||||||
name: String,
|
name: String,
|
||||||
is_default: bool,
|
is_default: bool,
|
||||||
user_id: String,
|
user_id: String,
|
||||||
entries: Vec<CollectionObject>
|
entries: Vec<CollectionObject>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
#[derive(Serialize, Deserialize, Debug, Clone, Default)]
|
||||||
@ -21,4 +21,3 @@ pub struct CollectionObject {
|
|||||||
game_id: String,
|
game_id: String,
|
||||||
game: Game,
|
game: Game,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -2,7 +2,12 @@ use reqwest::blocking::Client;
|
|||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{database::db::DatabaseImpls, error::remote_access_error::RemoteAccessError, remote::{auth::generate_authorization_header, requests::make_request}, DB};
|
use crate::{
|
||||||
|
database::db::DatabaseImpls,
|
||||||
|
error::remote_access_error::RemoteAccessError,
|
||||||
|
remote::{auth::generate_authorization_header, requests::make_request},
|
||||||
|
DB,
|
||||||
|
};
|
||||||
|
|
||||||
use super::collection::{Collection, Collections};
|
use super::collection::{Collection, Collections};
|
||||||
|
|
||||||
@ -20,9 +25,12 @@ pub fn fetch_collections() -> Result<Collections, RemoteAccessError> {
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn fetch_collection(collection_id: String) -> Result<Collection, RemoteAccessError> {
|
pub fn fetch_collection(collection_id: String) -> Result<Collection, RemoteAccessError> {
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
let response = make_request(&client, &["/api/v1/client/collection/", &collection_id], &[], |r| {
|
let response = make_request(
|
||||||
r.header("Authorization", generate_authorization_header())
|
&client,
|
||||||
})?
|
&["/api/v1/client/collection/", &collection_id],
|
||||||
|
&[],
|
||||||
|
|r| r.header("Authorization", generate_authorization_header()),
|
||||||
|
)?
|
||||||
.send()?;
|
.send()?;
|
||||||
|
|
||||||
Ok(response.json()?)
|
Ok(response.json()?)
|
||||||
@ -35,20 +43,26 @@ pub fn create_collection(name: String) -> Result<Collection, RemoteAccessError>
|
|||||||
|
|
||||||
let base_url = Url::parse(&format!("{}api/v1/client/collection/", base_url))?;
|
let base_url = Url::parse(&format!("{}api/v1/client/collection/", base_url))?;
|
||||||
|
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.post(base_url)
|
.post(base_url)
|
||||||
.header("Authorization", generate_authorization_header())
|
.header("Authorization", generate_authorization_header())
|
||||||
.json(&json!({"name": name}))
|
.json(&json!({"name": name}))
|
||||||
.send()?;
|
.send()?;
|
||||||
|
|
||||||
Ok(response.json()?)
|
Ok(response.json()?)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn add_game_to_collection(collection_id: String, game_id: String) -> Result<(), RemoteAccessError> {
|
pub fn add_game_to_collection(
|
||||||
|
collection_id: String,
|
||||||
|
game_id: String,
|
||||||
|
) -> Result<(), RemoteAccessError> {
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
let url = Url::parse(&format!("{}api/v1/client/collection/{}/entry/", DB.fetch_base_url(), collection_id))?;
|
let url = Url::parse(&format!(
|
||||||
|
"{}api/v1/client/collection/{}/entry/",
|
||||||
|
DB.fetch_base_url(),
|
||||||
|
collection_id
|
||||||
|
))?;
|
||||||
|
|
||||||
client
|
client
|
||||||
.post(url)
|
.post(url)
|
||||||
@ -61,7 +75,11 @@ pub fn add_game_to_collection(collection_id: String, game_id: String) -> Result<
|
|||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn delete_collection(collection_id: String) -> Result<bool, RemoteAccessError> {
|
pub fn delete_collection(collection_id: String) -> Result<bool, RemoteAccessError> {
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
let base_url = Url::parse(&format!("{}api/v1/client/collection/{}", DB.fetch_base_url(), collection_id))?;
|
let base_url = Url::parse(&format!(
|
||||||
|
"{}api/v1/client/collection/{}",
|
||||||
|
DB.fetch_base_url(),
|
||||||
|
collection_id
|
||||||
|
))?;
|
||||||
|
|
||||||
let response = client
|
let response = client
|
||||||
.delete(base_url)
|
.delete(base_url)
|
||||||
@ -71,9 +89,16 @@ pub fn delete_collection(collection_id: String) -> Result<bool, RemoteAccessErro
|
|||||||
Ok(response.json()?)
|
Ok(response.json()?)
|
||||||
}
|
}
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn delete_game_in_collection(collection_id: String, game_id: String) -> Result<(), RemoteAccessError> {
|
pub fn delete_game_in_collection(
|
||||||
|
collection_id: String,
|
||||||
|
game_id: String,
|
||||||
|
) -> Result<(), RemoteAccessError> {
|
||||||
let client = Client::new();
|
let client = Client::new();
|
||||||
let base_url = Url::parse(&format!("{}api/v1/client/collection/{}/entry", DB.fetch_base_url(), collection_id))?;
|
let base_url = Url::parse(&format!(
|
||||||
|
"{}api/v1/client/collection/{}/entry",
|
||||||
|
DB.fetch_base_url(),
|
||||||
|
collection_id
|
||||||
|
))?;
|
||||||
|
|
||||||
client
|
client
|
||||||
.delete(base_url)
|
.delete(base_url)
|
||||||
@ -82,4 +107,4 @@ pub fn delete_game_in_collection(collection_id: String, game_id: String) -> Resu
|
|||||||
.send()?;
|
.send()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,2 +1,2 @@
|
|||||||
|
pub mod collection;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod collection;
|
|
||||||
@ -1,6 +1,6 @@
|
|||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::AppHandle;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::models::data::GameVersion,
|
database::models::data::GameVersion,
|
||||||
|
|||||||
@ -3,9 +3,7 @@ use std::sync::{Arc, Mutex};
|
|||||||
use crate::{
|
use crate::{
|
||||||
download_manager::{
|
download_manager::{
|
||||||
download_manager::DownloadManagerSignal, downloadable::Downloadable,
|
download_manager::DownloadManagerSignal, downloadable::Downloadable,
|
||||||
internal_error::InternalError,
|
}, error::download_manager_error::DownloadManagerError, AppState
|
||||||
},
|
|
||||||
AppState,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::download_agent::GameDownloadAgent;
|
use super::download_agent::GameDownloadAgent;
|
||||||
@ -16,7 +14,7 @@ pub fn download_game(
|
|||||||
game_version: String,
|
game_version: String,
|
||||||
install_dir: usize,
|
install_dir: usize,
|
||||||
state: tauri::State<'_, Mutex<AppState>>,
|
state: tauri::State<'_, Mutex<AppState>>,
|
||||||
) -> Result<(), InternalError<DownloadManagerSignal>> {
|
) -> Result<(), DownloadManagerError<DownloadManagerSignal>> {
|
||||||
let sender = state.lock().unwrap().download_manager.get_sender();
|
let sender = state.lock().unwrap().download_manager.get_sender();
|
||||||
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new(
|
let game_download_agent = Arc::new(Box::new(GameDownloadAgent::new(
|
||||||
game_id,
|
game_id,
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
use crate::auth::generate_authorization_header;
|
use crate::auth::generate_authorization_header;
|
||||||
use crate::database::db::borrow_db_checked;
|
use crate::database::db::borrow_db_checked;
|
||||||
use crate::database::models::data::{ApplicationTransientStatus, DownloadType, DownloadableMetadata, GameDownloadStatus};
|
use crate::database::models::data::{
|
||||||
use crate::download_manager::download_manager::{DownloadManagerSignal, DownloadStatus};
|
ApplicationTransientStatus, DownloadType, DownloadableMetadata, GameDownloadStatus,
|
||||||
use crate::download_manager::download_thread_control_flag::{
|
|
||||||
DownloadThreadControl, DownloadThreadControlFlag,
|
|
||||||
};
|
};
|
||||||
|
use crate::download_manager::download_manager::{DownloadManagerSignal, DownloadStatus};
|
||||||
use crate::download_manager::downloadable::Downloadable;
|
use crate::download_manager::downloadable::Downloadable;
|
||||||
use crate::download_manager::progress_object::{ProgressHandle, ProgressObject};
|
use crate::download_manager::util::download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag};
|
||||||
|
use crate::download_manager::util::progress_object::{ProgressHandle, ProgressObject};
|
||||||
use crate::error::application_download_error::ApplicationDownloadError;
|
use crate::error::application_download_error::ApplicationDownloadError;
|
||||||
use crate::error::remote_access_error::RemoteAccessError;
|
use crate::error::remote_access_error::RemoteAccessError;
|
||||||
use crate::games::downloads::manifest::{DropDownloadContext, DropManifest};
|
use crate::games::downloads::manifest::{DropDownloadContext, DropManifest};
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
use crate::download_manager::download_thread_control_flag::{
|
use crate::download_manager::util::download_thread_control_flag::{DownloadThreadControl, DownloadThreadControlFlag};
|
||||||
DownloadThreadControl, DownloadThreadControlFlag,
|
use crate::download_manager::util::progress_object::ProgressHandle;
|
||||||
};
|
|
||||||
use crate::download_manager::progress_object::ProgressHandle;
|
|
||||||
use crate::error::application_download_error::ApplicationDownloadError;
|
use crate::error::application_download_error::ApplicationDownloadError;
|
||||||
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;
|
||||||
|
|||||||
@ -2,13 +2,15 @@ use std::fs::remove_dir_all;
|
|||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::thread::spawn;
|
use std::thread::spawn;
|
||||||
|
|
||||||
use log::{debug, error, info, warn};
|
use log::{debug, error, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use tauri::Emitter;
|
use tauri::Emitter;
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::AppHandle;
|
||||||
|
|
||||||
use crate::database::db::{borrow_db_checked, borrow_db_mut_checked, save_db};
|
use crate::database::db::{borrow_db_checked, borrow_db_mut_checked, save_db};
|
||||||
use crate::database::models::data::{ApplicationTransientStatus, DownloadableMetadata, GameDownloadStatus, GameVersion};
|
use crate::database::models::data::{
|
||||||
|
ApplicationTransientStatus, DownloadableMetadata, GameDownloadStatus, GameVersion,
|
||||||
|
};
|
||||||
use crate::download_manager::download_manager::DownloadStatus;
|
use crate::download_manager::download_manager::DownloadStatus;
|
||||||
use crate::error::library_error::LibraryError;
|
use crate::error::library_error::LibraryError;
|
||||||
use crate::error::remote_access_error::RemoteAccessError;
|
use crate::error::remote_access_error::RemoteAccessError;
|
||||||
|
|||||||
@ -1,5 +1,5 @@
|
|||||||
|
pub mod collections;
|
||||||
pub mod commands;
|
pub mod commands;
|
||||||
pub mod downloads;
|
pub mod downloads;
|
||||||
pub mod library;
|
pub mod library;
|
||||||
pub mod state;
|
pub mod state;
|
||||||
pub mod collections;
|
|
||||||
@ -1,4 +1,7 @@
|
|||||||
use crate::database::{db::borrow_db_checked, models::data::{ApplicationTransientStatus, GameDownloadStatus}};
|
use crate::database::{
|
||||||
|
db::borrow_db_checked,
|
||||||
|
models::data::{ApplicationTransientStatus, GameDownloadStatus},
|
||||||
|
};
|
||||||
|
|
||||||
pub type GameStatusWithTransient = (
|
pub type GameStatusWithTransient = (
|
||||||
Option<GameDownloadStatus>,
|
Option<GameDownloadStatus>,
|
||||||
|
|||||||
@ -1,18 +1,18 @@
|
|||||||
mod database;
|
mod database;
|
||||||
mod games;
|
mod games;
|
||||||
|
|
||||||
mod autostart;
|
mod client;
|
||||||
mod cleanup;
|
|
||||||
mod commands;
|
|
||||||
mod download_manager;
|
mod download_manager;
|
||||||
mod error;
|
mod error;
|
||||||
mod process;
|
mod process;
|
||||||
mod remote;
|
mod remote;
|
||||||
|
|
||||||
use crate::database::db::DatabaseImpls;
|
use crate::database::db::DatabaseImpls;
|
||||||
use autostart::{get_autostart_enabled, toggle_autostart};
|
use client::{
|
||||||
use cleanup::{cleanup_and_exit, quit};
|
autostart::{get_autostart_enabled, sync_autostart_on_startup, toggle_autostart},
|
||||||
use commands::fetch_state;
|
cleanup::{cleanup_and_exit, quit},
|
||||||
|
};
|
||||||
|
use client::commands::fetch_state;
|
||||||
use database::commands::{
|
use database::commands::{
|
||||||
add_download_dir, delete_download_dir, fetch_download_dir_stats, fetch_settings,
|
add_download_dir, delete_download_dir, fetch_download_dir_stats, fetch_settings,
|
||||||
fetch_system_data, update_settings,
|
fetch_system_data, update_settings,
|
||||||
@ -33,7 +33,6 @@ use games::commands::{
|
|||||||
};
|
};
|
||||||
use games::downloads::commands::download_game;
|
use games::downloads::commands::download_game;
|
||||||
use games::library::{update_game_configuration, Game};
|
use games::library::{update_game_configuration, Game};
|
||||||
use http::Response;
|
|
||||||
use log::{debug, info, warn, LevelFilter};
|
use log::{debug, info, warn, LevelFilter};
|
||||||
use log4rs::append::console::ConsoleAppender;
|
use log4rs::append::console::ConsoleAppender;
|
||||||
use log4rs::append::file::FileAppender;
|
use log4rs::append::file::FileAppender;
|
||||||
@ -48,9 +47,7 @@ use remote::commands::{
|
|||||||
sign_out, use_remote,
|
sign_out, use_remote,
|
||||||
};
|
};
|
||||||
use remote::fetch_object::{fetch_object, fetch_object_offline};
|
use remote::fetch_object::{fetch_object, fetch_object_offline};
|
||||||
use remote::requests::make_request;
|
|
||||||
use remote::server_proto::{handle_server_proto, handle_server_proto_offline};
|
use remote::server_proto::{handle_server_proto, handle_server_proto_offline};
|
||||||
use reqwest::blocking::Body;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
@ -196,7 +193,7 @@ fn setup(handle: AppHandle) -> AppState<'static> {
|
|||||||
debug!("finished setup!");
|
debug!("finished setup!");
|
||||||
|
|
||||||
// Sync autostart state
|
// Sync autostart state
|
||||||
if let Err(e) = autostart::sync_autostart_on_startup(&handle) {
|
if let Err(e) = sync_autostart_on_startup(&handle) {
|
||||||
warn!("failed to sync autostart state: {}", e);
|
warn!("failed to sync autostart state: {}", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,13 +1 @@
|
|||||||
// Since this code isn't being used, we can either:
|
|
||||||
// 1. Delete the entire file if compatibility features are not planned
|
|
||||||
// 2. Or add a TODO comment if planning to implement later
|
|
||||||
|
|
||||||
// Option 1: Delete the file
|
|
||||||
// Delete src-tauri/src/process/compat.rs
|
|
||||||
|
|
||||||
// Option 2: Add TODO comment
|
|
||||||
/*
|
|
||||||
TODO: Compatibility layer for running Windows games on Linux
|
|
||||||
This module is currently unused but reserved for future implementation
|
|
||||||
of Windows game compatibility features on Linux.
|
|
||||||
*/
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
pub mod commands;
|
pub mod commands;
|
||||||
|
#[cfg(target_os = "linux")]
|
||||||
pub mod compat;
|
pub mod compat;
|
||||||
pub mod process_manager;
|
pub mod process_manager;
|
||||||
|
|||||||
@ -1,9 +1,9 @@
|
|||||||
use std::{
|
use std::{
|
||||||
collections::HashMap,
|
collections::HashMap,
|
||||||
fs::{File, OpenOptions},
|
fs::OpenOptions,
|
||||||
io::{self, Error},
|
io::{self},
|
||||||
path::{Path, PathBuf},
|
path::PathBuf,
|
||||||
process::{Child, Command, ExitStatus},
|
process::{Command, ExitStatus},
|
||||||
str::FromStr,
|
str::FromStr,
|
||||||
sync::{Arc, Mutex},
|
sync::{Arc, Mutex},
|
||||||
thread::spawn,
|
thread::spawn,
|
||||||
@ -15,12 +15,14 @@ use log::{debug, info, warn};
|
|||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use shared_child::SharedChild;
|
use shared_child::SharedChild;
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::{AppHandle, Manager};
|
||||||
use umu_wrapper_lib::command_builder::UmuCommandBuilder;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::{
|
database::{
|
||||||
db::{borrow_db_mut_checked, DATA_ROOT_DIR},
|
db::{borrow_db_mut_checked, DATA_ROOT_DIR},
|
||||||
models::data::{ApplicationTransientStatus, DownloadType, DownloadableMetadata, GameDownloadStatus, GameVersion},
|
models::data::{
|
||||||
|
ApplicationTransientStatus, DownloadType, DownloadableMetadata, GameDownloadStatus,
|
||||||
|
GameVersion,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
error::process_error::ProcessError,
|
error::process_error::ProcessError,
|
||||||
games::{library::push_game_update, state::GameStatusManager},
|
games::{library::push_game_update, state::GameStatusManager},
|
||||||
@ -46,7 +48,7 @@ impl ProcessManager<'_> {
|
|||||||
current_platform: Platform::Windows,
|
current_platform: Platform::Windows,
|
||||||
|
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
current_platform: Platform::macOS,
|
current_platform: Platform::MacOs,
|
||||||
|
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
current_platform: Platform::Linux,
|
current_platform: Platform::Linux,
|
||||||
@ -65,7 +67,7 @@ impl ProcessManager<'_> {
|
|||||||
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
(Platform::macOS, Platform::macOS),
|
(Platform::MacOs, Platform::MacOs),
|
||||||
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
&NativeGameLauncher {} as &(dyn ProcessHandler + Sync + Send + 'static),
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
@ -330,7 +332,7 @@ impl ProcessManager<'_> {
|
|||||||
pub enum Platform {
|
pub enum Platform {
|
||||||
Windows,
|
Windows,
|
||||||
Linux,
|
Linux,
|
||||||
macOS,
|
MacOs,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait ProcessHandler: Send + 'static {
|
pub trait ProcessHandler: Send + 'static {
|
||||||
@ -351,14 +353,14 @@ impl ProcessHandler for NativeGameLauncher {
|
|||||||
_meta: &DownloadableMetadata,
|
_meta: &DownloadableMetadata,
|
||||||
launch_command: String,
|
launch_command: String,
|
||||||
args: Vec<String>,
|
args: Vec<String>,
|
||||||
game_version: &GameVersion,
|
_game_version: &GameVersion,
|
||||||
current_dir: &str,
|
_current_dir: &str,
|
||||||
) -> String {
|
) -> String {
|
||||||
format!("\"{}\" {}", launch_command, args.join(" "))
|
format!("\"{}\" {}", launch_command, args.join(" "))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const UMU_LAUNCHER_EXECUTABLE: &str = "umu-run";
|
pub const UMU_LAUNCHER_EXECUTABLE: &str = "umu-run";
|
||||||
struct UMULauncher;
|
struct UMULauncher;
|
||||||
impl ProcessHandler for UMULauncher {
|
impl ProcessHandler for UMULauncher {
|
||||||
fn create_launch_process(
|
fn create_launch_process(
|
||||||
|
|||||||
@ -1,21 +1,20 @@
|
|||||||
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, warn};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use tauri::{AppHandle, Emitter};
|
||||||
use tauri::{AppHandle, Emitter, Manager};
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::{
|
database::{
|
||||||
db::{borrow_db_checked, borrow_db_mut_checked, save_db, DatabaseImpls},
|
db::{borrow_db_checked, borrow_db_mut_checked, save_db},
|
||||||
models::data::DatabaseAuth,
|
models::data::DatabaseAuth,
|
||||||
},
|
},
|
||||||
error::{drop_server_error::DropServerError, remote_access_error::RemoteAccessError},
|
error::{drop_server_error::DropServerError, remote_access_error::RemoteAccessError},
|
||||||
AppState, AppStatus, User, DB,
|
AppStatus, User,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::sync::RwLockReadGuard;
|
use crate::{
|
||||||
|
database::{db::borrow_db_checked, models::data::Database},
|
||||||
use crate::{database::{db::borrow_db_checked, models::data::Database}, error::remote_access_error::RemoteAccessError};
|
error::remote_access_error::RemoteAccessError,
|
||||||
|
};
|
||||||
use cacache::Integrity;
|
use cacache::Integrity;
|
||||||
use http::{header::CONTENT_TYPE, response::Builder as ResponseBuilder, Response};
|
use http::{header::CONTENT_TYPE, response::Builder as ResponseBuilder, Response};
|
||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
|
|||||||
@ -6,11 +6,16 @@ use tauri::{AppHandle, Emitter, Manager};
|
|||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
database::db::{borrow_db_checked, borrow_db_mut_checked, save_db}, error::remote_access_error::RemoteAccessError, remote::{auth::generate_authorization_header, requests::make_request}, AppState, AppStatus
|
database::db::{borrow_db_checked, borrow_db_mut_checked, save_db},
|
||||||
|
error::remote_access_error::RemoteAccessError,
|
||||||
|
remote::{auth::generate_authorization_header, requests::make_request},
|
||||||
|
AppState, AppStatus,
|
||||||
};
|
};
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
auth::{auth_initiate_logic, recieve_handshake, setup}, cache::{cache_object, get_cached_object}, remote::use_remote_logic
|
auth::{auth_initiate_logic, recieve_handshake, setup},
|
||||||
|
cache::{cache_object, get_cached_object},
|
||||||
|
remote::use_remote_logic,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@ -36,24 +41,22 @@ pub fn gen_drop_url(path: String) -> Result<String, RemoteAccessError> {
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn fetch_drop_object(path: String) -> Result<Vec<u8>, RemoteAccessError> {
|
pub fn fetch_drop_object(path: String) -> Result<Vec<u8>, RemoteAccessError> {
|
||||||
let drop_url = gen_drop_url(path.clone());
|
let _drop_url = gen_drop_url(path.clone())?;
|
||||||
let req = make_request(
|
let req = make_request(&Client::new(), &[&path], &[], |r| {
|
||||||
&Client::new(),
|
r.header("Authorization", generate_authorization_header())
|
||||||
&[&path],
|
})?
|
||||||
&[],
|
.send();
|
||||||
|r| { r.header("Authorization", generate_authorization_header()) }
|
|
||||||
)?.send();
|
|
||||||
|
|
||||||
match req {
|
match req {
|
||||||
Ok(data) => {
|
Ok(data) => {
|
||||||
let data = data.bytes()?.to_vec();
|
let data = data.bytes()?.to_vec();
|
||||||
cache_object(&path, &data)?;
|
cache_object(&path, &data)?;
|
||||||
Ok(data)
|
Ok(data)
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
debug!("{}", e);
|
debug!("{}", e);
|
||||||
get_cached_object::<&str, Vec<u8>>(&path)
|
get_cached_object::<&str, Vec<u8>>(&path)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|||||||
@ -2,12 +2,13 @@ use http::{header::CONTENT_TYPE, response::Builder as ResponseBuilder};
|
|||||||
use log::warn;
|
use log::warn;
|
||||||
use tauri::UriSchemeResponder;
|
use tauri::UriSchemeResponder;
|
||||||
|
|
||||||
use super::{auth::generate_authorization_header, cache::{cache_object, get_cached_object, ObjectCache}, requests::make_request};
|
use super::{
|
||||||
|
auth::generate_authorization_header,
|
||||||
|
cache::{cache_object, get_cached_object, ObjectCache},
|
||||||
|
requests::make_request,
|
||||||
|
};
|
||||||
|
|
||||||
pub fn fetch_object(
|
pub fn fetch_object(request: http::Request<Vec<u8>>, responder: UriSchemeResponder) {
|
||||||
request: http::Request<Vec<u8>>,
|
|
||||||
responder: UriSchemeResponder,
|
|
||||||
) {
|
|
||||||
// Drop leading /
|
// Drop leading /
|
||||||
let object_id = &request.uri().path()[1..];
|
let object_id = &request.uri().path()[1..];
|
||||||
|
|
||||||
@ -25,7 +26,7 @@ pub fn fetch_object(
|
|||||||
Ok(data) => responder.respond(data.into()),
|
Ok(data) => responder.respond(data.into()),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("{}", e)
|
warn!("{}", e)
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -41,10 +42,7 @@ pub fn fetch_object(
|
|||||||
|
|
||||||
responder.respond(resp);
|
responder.respond(resp);
|
||||||
}
|
}
|
||||||
pub fn fetch_object_offline(
|
pub fn fetch_object_offline(request: http::Request<Vec<u8>>, responder: UriSchemeResponder) {
|
||||||
request: http::Request<Vec<u8>>,
|
|
||||||
responder: UriSchemeResponder,
|
|
||||||
) {
|
|
||||||
let object_id = &request.uri().path()[1..];
|
let object_id = &request.uri().path()[1..];
|
||||||
let data = get_cached_object::<&str, ObjectCache>(object_id);
|
let data = get_cached_object::<&str, ObjectCache>(object_id);
|
||||||
|
|
||||||
|
|||||||
@ -5,4 +5,4 @@ pub mod commands;
|
|||||||
pub mod fetch_object;
|
pub mod fetch_object;
|
||||||
pub mod remote;
|
pub mod remote;
|
||||||
pub mod requests;
|
pub mod requests;
|
||||||
pub mod server_proto;
|
pub mod server_proto;
|
||||||
|
|||||||
@ -1,10 +1,9 @@
|
|||||||
use std::{path::PathBuf, str::FromStr};
|
use std::str::FromStr;
|
||||||
|
|
||||||
use http::{
|
use http::{
|
||||||
uri::{Authority, PathAndQuery},
|
uri::PathAndQuery,
|
||||||
Request, Response, StatusCode, Uri,
|
Request, Response, StatusCode, Uri,
|
||||||
};
|
};
|
||||||
use log::info;
|
|
||||||
use reqwest::blocking::Client;
|
use reqwest::blocking::Client;
|
||||||
use tauri::UriSchemeResponder;
|
use tauri::UriSchemeResponder;
|
||||||
|
|
||||||
|
|||||||
@ -1,5 +1,4 @@
|
|||||||
/* automatically generated by rust-bindgen 0.71.1 */
|
/* automatically generated by rust-bindgen 0.71.1 */
|
||||||
|
|
||||||
#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
|
#[derive(PartialEq, Copy, Clone, Hash, Debug, Default)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
pub struct __BindgenComplex<T> {
|
pub struct __BindgenComplex<T> {
|
||||||
|
|||||||
Reference in New Issue
Block a user