mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2025-11-10 04:22:13 +10:00
feat(download manager): only allow downloads for supported platforms
This commit is contained in:
@ -168,7 +168,7 @@
|
||||
</div>
|
||||
<div class="ml-3">
|
||||
<h3 class="text-sm font-medium text-red-600">
|
||||
There are no versions to install. Please contact your
|
||||
There are no supported versions to install. Please contact your
|
||||
server admin or try again later.
|
||||
</h3>
|
||||
</div>
|
||||
|
||||
@ -11,7 +11,7 @@ use rustbreak::{DeSerError, DeSerializer, PathDatabase};
|
||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
use crate::DB;
|
||||
use crate::{process::process_manager::Platform, DB};
|
||||
|
||||
#[derive(serde::Serialize, Clone, Deserialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
@ -26,11 +26,21 @@ pub struct DatabaseAuth {
|
||||
#[serde(tag = "type")]
|
||||
pub enum DatabaseGameStatus {
|
||||
Remote {},
|
||||
Queued { version_name: String },
|
||||
Downloading { version_name: String },
|
||||
SetupRequired { version_name: String },
|
||||
Installed { version_name: String },
|
||||
Updating { version_name: String },
|
||||
Queued {
|
||||
version_name: String,
|
||||
},
|
||||
Downloading {
|
||||
version_name: String,
|
||||
},
|
||||
SetupRequired {
|
||||
version_name: String,
|
||||
},
|
||||
Installed {
|
||||
version_name: String,
|
||||
},
|
||||
Updating {
|
||||
version_name: String,
|
||||
},
|
||||
Uninstalling {},
|
||||
}
|
||||
|
||||
@ -41,7 +51,7 @@ pub struct GameVersion {
|
||||
pub version_name: String,
|
||||
pub launch_command: String,
|
||||
pub setup_command: String,
|
||||
pub platform: String,
|
||||
pub platform: Platform,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Clone, Deserialize)]
|
||||
@ -111,7 +121,10 @@ impl DatabaseImpls for DatabaseInterface {
|
||||
game_versions: HashMap::new(),
|
||||
},
|
||||
};
|
||||
debug!("Creating database at path {}", db_path.as_os_str().to_str().unwrap());
|
||||
debug!(
|
||||
"Creating database at path {}",
|
||||
db_path.as_os_str().to_str().unwrap()
|
||||
);
|
||||
PathDatabase::create_at_path(db_path, default)
|
||||
.expect("Database could not be created")
|
||||
}
|
||||
|
||||
@ -37,6 +37,8 @@ pub enum DownloadManagerSignal {
|
||||
Error(GameDownloadError),
|
||||
/// Pushes UI update
|
||||
Update,
|
||||
/// Causes the Download Agent status to be synced to disk
|
||||
Sync(usize),
|
||||
}
|
||||
pub enum DownloadManagerStatus {
|
||||
Downloading,
|
||||
|
||||
@ -141,6 +141,8 @@ impl DownloadManagerBuilder {
|
||||
self.app_handle.emit("update_queue", event_data).unwrap();
|
||||
}
|
||||
|
||||
fn sync_download_agent(&self) {}
|
||||
|
||||
fn remove_and_cleanup_game(&mut self, game_id: &String) -> Arc<GameDownloadAgent> {
|
||||
self.download_queue.pop_front();
|
||||
let download_agent = self.download_agent_registry.remove(game_id).unwrap();
|
||||
@ -195,6 +197,9 @@ impl DownloadManagerBuilder {
|
||||
DownloadManagerSignal::Update => {
|
||||
self.push_manager_update();
|
||||
}
|
||||
DownloadManagerSignal::Sync(index) => {
|
||||
self.sync_download_agent();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@ -2,7 +2,8 @@ mod auth;
|
||||
mod db;
|
||||
mod downloads;
|
||||
mod library;
|
||||
// mod p2p;
|
||||
|
||||
mod process;
|
||||
mod remote;
|
||||
mod settings;
|
||||
#[cfg(test)]
|
||||
@ -25,6 +26,7 @@ use log4rs::append::file::FileAppender;
|
||||
use log4rs::config::{Appender, Root};
|
||||
use log4rs::encode::pattern::PatternEncoder;
|
||||
use log4rs::Config;
|
||||
use process::process_manager::ProcessManager;
|
||||
use remote::{gen_drop_url, use_remote};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::sync::Arc;
|
||||
@ -64,6 +66,8 @@ pub struct AppState {
|
||||
|
||||
#[serde(skip_serializing)]
|
||||
download_manager: Arc<DownloadManager>,
|
||||
#[serde(skip_serializing)]
|
||||
process_manager: Arc<ProcessManager>,
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
@ -81,7 +85,7 @@ fn setup(handle: AppHandle) -> AppState {
|
||||
.unwrap();
|
||||
|
||||
let console = ConsoleAppender::builder()
|
||||
.encoder(Box::new(PatternEncoder::new("{d} | {l} | {f} - {m}{n}\n")))
|
||||
.encoder(Box::new(PatternEncoder::new("{t}|{l}|{f} - {m}{n}")))
|
||||
.build();
|
||||
|
||||
let config = Config::builder()
|
||||
@ -100,6 +104,7 @@ fn setup(handle: AppHandle) -> AppState {
|
||||
|
||||
let games = HashMap::new();
|
||||
let download_manager = Arc::new(DownloadManagerBuilder::build(handle));
|
||||
let process_manager = Arc::new(ProcessManager::new());
|
||||
|
||||
debug!("Checking if database is set up");
|
||||
let is_set_up = DB.database_is_set_up();
|
||||
@ -109,6 +114,7 @@ fn setup(handle: AppHandle) -> AppState {
|
||||
user: None,
|
||||
games,
|
||||
download_manager,
|
||||
process_manager,
|
||||
};
|
||||
}
|
||||
|
||||
@ -120,6 +126,7 @@ fn setup(handle: AppHandle) -> AppState {
|
||||
user,
|
||||
games,
|
||||
download_manager,
|
||||
process_manager,
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,4 +241,6 @@ pub fn run() {
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
|
||||
info!("exiting drop application...");
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ use crate::db::DatabaseGameStatus;
|
||||
use crate::db::DatabaseImpls;
|
||||
use crate::db::GameVersion;
|
||||
use crate::downloads::download_manager::GameDownloadStatus;
|
||||
use crate::process::process_manager::Platform;
|
||||
use crate::remote::RemoteAccessError;
|
||||
use crate::{auth::generate_authorization_header, AppState, DB};
|
||||
|
||||
@ -56,7 +57,7 @@ pub struct QueueUpdateEvent {
|
||||
pub struct GameVersionOption {
|
||||
version_index: usize,
|
||||
version_name: String,
|
||||
platform: String,
|
||||
platform: Platform,
|
||||
setup_command: String,
|
||||
launch_command: String,
|
||||
delta: bool,
|
||||
@ -199,8 +200,9 @@ pub fn fetch_game_status(id: String) -> Result<DatabaseGameStatus, String> {
|
||||
Ok(status)
|
||||
}
|
||||
|
||||
fn fetch_game_verion_options_logic(
|
||||
fn fetch_game_verion_options_logic<'a>(
|
||||
game_id: String,
|
||||
state: tauri::State<'_, Mutex<AppState>>,
|
||||
) -> Result<Vec<GameVersionOption>, RemoteAccessError> {
|
||||
let base_url = DB.fetch_base_url();
|
||||
|
||||
@ -222,12 +224,27 @@ fn fetch_game_verion_options_logic(
|
||||
|
||||
let data = response.json::<Vec<GameVersionOption>>()?;
|
||||
|
||||
let state_lock = state.lock().unwrap();
|
||||
let data = data
|
||||
.into_iter()
|
||||
.filter(|v| {
|
||||
state_lock
|
||||
.process_manager
|
||||
.valid_platform(&v.platform)
|
||||
.unwrap()
|
||||
})
|
||||
.collect::<Vec<GameVersionOption>>();
|
||||
drop(state_lock);
|
||||
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub fn fetch_game_verion_options(game_id: String) -> Result<Vec<GameVersionOption>, String> {
|
||||
fetch_game_verion_options_logic(game_id).map_err(|e| e.to_string())
|
||||
pub fn fetch_game_verion_options<'a>(
|
||||
game_id: String,
|
||||
state: tauri::State<'_, Mutex<AppState>>,
|
||||
) -> Result<Vec<GameVersionOption>, String> {
|
||||
fetch_game_verion_options_logic(game_id, state).map_err(|e| e.to_string())
|
||||
}
|
||||
|
||||
pub fn on_game_complete(
|
||||
|
||||
@ -1,26 +0,0 @@
|
||||
use serde::{Deserialize, Serialize};
|
||||
use url::Url;
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct P2PManager {
|
||||
peers: Vec<Peer>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Debug)]
|
||||
pub struct Peer {
|
||||
endpoints: Vec<Url>,
|
||||
current_endpoint: usize,
|
||||
// TODO: Implement Wireguard tunnels
|
||||
}
|
||||
|
||||
impl Peer {
|
||||
pub fn get_current_endpoint(&self) -> Url {
|
||||
self.endpoints[self.current_endpoint].clone()
|
||||
}
|
||||
pub fn connect(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
pub fn disconnect(&mut self) {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
@ -1 +0,0 @@
|
||||
pub mod discovery;
|
||||
@ -1,17 +0,0 @@
|
||||
use crate::{auth::generate_authorization_header, db::DatabaseImpls, remote::RemoteAccessError, DB};
|
||||
|
||||
|
||||
pub async fn register() -> Result<String, RemoteAccessError> {
|
||||
let base_url = DB.fetch_base_url();
|
||||
let registration_url = base_url.join("/api/v1/client/capability").unwrap();
|
||||
let header = generate_authorization_header();
|
||||
|
||||
|
||||
let client = reqwest::blocking::Client::new();
|
||||
client
|
||||
.post(registration_url)
|
||||
.header("Authorization", header)
|
||||
.send()?;
|
||||
|
||||
return Ok(String::new())
|
||||
}
|
||||
1
src-tauri/src/process/mod.rs
Normal file
1
src-tauri/src/process/mod.rs
Normal file
@ -0,0 +1 @@
|
||||
pub mod process_manager;
|
||||
45
src-tauri/src/process/process_manager.rs
Normal file
45
src-tauri/src/process/process_manager.rs
Normal file
@ -0,0 +1,45 @@
|
||||
use std::{collections::HashMap, sync::LazyLock};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub struct ProcessManager {
|
||||
current_platform: Platform,
|
||||
}
|
||||
|
||||
impl ProcessManager {
|
||||
pub fn new() -> Self {
|
||||
ProcessManager {
|
||||
current_platform: if cfg!(windows) {
|
||||
Platform::Windows
|
||||
} else {
|
||||
Platform::Linux
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
pub fn valid_platform(&self, platform: &Platform) -> Result<bool, String> {
|
||||
let current = &self.current_platform;
|
||||
let valid_platforms = PROCESS_COMPATABILITY_MATRIX
|
||||
.get(current)
|
||||
.ok_or("Incomplete platform compatability matrix.")?;
|
||||
|
||||
Ok(valid_platforms.contains(platform))
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Eq, Hash, PartialEq, Serialize, Deserialize, Clone)]
|
||||
pub enum Platform {
|
||||
Windows,
|
||||
Linux,
|
||||
}
|
||||
|
||||
pub type ProcessCompatabilityMatrix = HashMap<Platform, Vec<Platform>>;
|
||||
pub static PROCESS_COMPATABILITY_MATRIX: LazyLock<ProcessCompatabilityMatrix> =
|
||||
LazyLock::new(|| {
|
||||
let mut matrix: ProcessCompatabilityMatrix = HashMap::new();
|
||||
|
||||
matrix.insert(Platform::Windows, vec![Platform::Windows]);
|
||||
matrix.insert(Platform::Linux, vec![Platform::Linux]); // TODO: add Proton support
|
||||
|
||||
return matrix;
|
||||
});
|
||||
Reference in New Issue
Block a user