mirror of
https://github.com/Drop-OSS/drop-app.git
synced 2026-07-27 02:04:46 +10:00
feat(download manager): only allow downloads for supported platforms
This commit is contained in:
@@ -168,7 +168,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="ml-3">
|
<div class="ml-3">
|
||||||
<h3 class="text-sm font-medium text-red-600">
|
<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.
|
server admin or try again later.
|
||||||
</h3>
|
</h3>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+21
-8
@@ -11,7 +11,7 @@ use rustbreak::{DeSerError, DeSerializer, PathDatabase};
|
|||||||
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use crate::DB;
|
use crate::{process::process_manager::Platform, DB};
|
||||||
|
|
||||||
#[derive(serde::Serialize, Clone, Deserialize)]
|
#[derive(serde::Serialize, Clone, Deserialize)]
|
||||||
#[serde(rename_all = "camelCase")]
|
#[serde(rename_all = "camelCase")]
|
||||||
@@ -26,11 +26,21 @@ pub struct DatabaseAuth {
|
|||||||
#[serde(tag = "type")]
|
#[serde(tag = "type")]
|
||||||
pub enum DatabaseGameStatus {
|
pub enum DatabaseGameStatus {
|
||||||
Remote {},
|
Remote {},
|
||||||
Queued { version_name: String },
|
Queued {
|
||||||
Downloading { version_name: String },
|
version_name: String,
|
||||||
SetupRequired { version_name: String },
|
},
|
||||||
Installed { version_name: String },
|
Downloading {
|
||||||
Updating { version_name: String },
|
version_name: String,
|
||||||
|
},
|
||||||
|
SetupRequired {
|
||||||
|
version_name: String,
|
||||||
|
},
|
||||||
|
Installed {
|
||||||
|
version_name: String,
|
||||||
|
},
|
||||||
|
Updating {
|
||||||
|
version_name: String,
|
||||||
|
},
|
||||||
Uninstalling {},
|
Uninstalling {},
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,7 +51,7 @@ pub struct GameVersion {
|
|||||||
pub version_name: String,
|
pub version_name: String,
|
||||||
pub launch_command: String,
|
pub launch_command: String,
|
||||||
pub setup_command: String,
|
pub setup_command: String,
|
||||||
pub platform: String,
|
pub platform: Platform,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Clone, Deserialize)]
|
#[derive(Serialize, Clone, Deserialize)]
|
||||||
@@ -111,7 +121,10 @@ impl DatabaseImpls for DatabaseInterface {
|
|||||||
game_versions: HashMap::new(),
|
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)
|
PathDatabase::create_at_path(db_path, default)
|
||||||
.expect("Database could not be created")
|
.expect("Database could not be created")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ pub enum DownloadManagerSignal {
|
|||||||
Error(GameDownloadError),
|
Error(GameDownloadError),
|
||||||
/// Pushes UI update
|
/// Pushes UI update
|
||||||
Update,
|
Update,
|
||||||
|
/// Causes the Download Agent status to be synced to disk
|
||||||
|
Sync(usize),
|
||||||
}
|
}
|
||||||
pub enum DownloadManagerStatus {
|
pub enum DownloadManagerStatus {
|
||||||
Downloading,
|
Downloading,
|
||||||
|
|||||||
@@ -141,6 +141,8 @@ impl DownloadManagerBuilder {
|
|||||||
self.app_handle.emit("update_queue", event_data).unwrap();
|
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> {
|
fn remove_and_cleanup_game(&mut self, game_id: &String) -> Arc<GameDownloadAgent> {
|
||||||
self.download_queue.pop_front();
|
self.download_queue.pop_front();
|
||||||
let download_agent = self.download_agent_registry.remove(game_id).unwrap();
|
let download_agent = self.download_agent_registry.remove(game_id).unwrap();
|
||||||
@@ -195,6 +197,9 @@ impl DownloadManagerBuilder {
|
|||||||
DownloadManagerSignal::Update => {
|
DownloadManagerSignal::Update => {
|
||||||
self.push_manager_update();
|
self.push_manager_update();
|
||||||
}
|
}
|
||||||
|
DownloadManagerSignal::Sync(index) => {
|
||||||
|
self.sync_download_agent();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-2
@@ -2,7 +2,8 @@ mod auth;
|
|||||||
mod db;
|
mod db;
|
||||||
mod downloads;
|
mod downloads;
|
||||||
mod library;
|
mod library;
|
||||||
// mod p2p;
|
|
||||||
|
mod process;
|
||||||
mod remote;
|
mod remote;
|
||||||
mod settings;
|
mod settings;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -25,6 +26,7 @@ use log4rs::append::file::FileAppender;
|
|||||||
use log4rs::config::{Appender, Root};
|
use log4rs::config::{Appender, Root};
|
||||||
use log4rs::encode::pattern::PatternEncoder;
|
use log4rs::encode::pattern::PatternEncoder;
|
||||||
use log4rs::Config;
|
use log4rs::Config;
|
||||||
|
use process::process_manager::ProcessManager;
|
||||||
use remote::{gen_drop_url, use_remote};
|
use remote::{gen_drop_url, use_remote};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -64,6 +66,8 @@ pub struct AppState {
|
|||||||
|
|
||||||
#[serde(skip_serializing)]
|
#[serde(skip_serializing)]
|
||||||
download_manager: Arc<DownloadManager>,
|
download_manager: Arc<DownloadManager>,
|
||||||
|
#[serde(skip_serializing)]
|
||||||
|
process_manager: Arc<ProcessManager>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
@@ -81,7 +85,7 @@ fn setup(handle: AppHandle) -> AppState {
|
|||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let console = ConsoleAppender::builder()
|
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();
|
.build();
|
||||||
|
|
||||||
let config = Config::builder()
|
let config = Config::builder()
|
||||||
@@ -100,6 +104,7 @@ fn setup(handle: AppHandle) -> AppState {
|
|||||||
|
|
||||||
let games = HashMap::new();
|
let games = HashMap::new();
|
||||||
let download_manager = Arc::new(DownloadManagerBuilder::build(handle));
|
let download_manager = Arc::new(DownloadManagerBuilder::build(handle));
|
||||||
|
let process_manager = Arc::new(ProcessManager::new());
|
||||||
|
|
||||||
debug!("Checking if database is set up");
|
debug!("Checking if database is set up");
|
||||||
let is_set_up = DB.database_is_set_up();
|
let is_set_up = DB.database_is_set_up();
|
||||||
@@ -109,6 +114,7 @@ fn setup(handle: AppHandle) -> AppState {
|
|||||||
user: None,
|
user: None,
|
||||||
games,
|
games,
|
||||||
download_manager,
|
download_manager,
|
||||||
|
process_manager,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,6 +126,7 @@ fn setup(handle: AppHandle) -> AppState {
|
|||||||
user,
|
user,
|
||||||
games,
|
games,
|
||||||
download_manager,
|
download_manager,
|
||||||
|
process_manager,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -234,4 +241,6 @@ pub fn run() {
|
|||||||
})
|
})
|
||||||
.run(tauri::generate_context!())
|
.run(tauri::generate_context!())
|
||||||
.expect("error while running tauri application");
|
.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::DatabaseImpls;
|
||||||
use crate::db::GameVersion;
|
use crate::db::GameVersion;
|
||||||
use crate::downloads::download_manager::GameDownloadStatus;
|
use crate::downloads::download_manager::GameDownloadStatus;
|
||||||
|
use crate::process::process_manager::Platform;
|
||||||
use crate::remote::RemoteAccessError;
|
use crate::remote::RemoteAccessError;
|
||||||
use crate::{auth::generate_authorization_header, AppState, DB};
|
use crate::{auth::generate_authorization_header, AppState, DB};
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@ pub struct QueueUpdateEvent {
|
|||||||
pub struct GameVersionOption {
|
pub struct GameVersionOption {
|
||||||
version_index: usize,
|
version_index: usize,
|
||||||
version_name: String,
|
version_name: String,
|
||||||
platform: String,
|
platform: Platform,
|
||||||
setup_command: String,
|
setup_command: String,
|
||||||
launch_command: String,
|
launch_command: String,
|
||||||
delta: bool,
|
delta: bool,
|
||||||
@@ -199,8 +200,9 @@ pub fn fetch_game_status(id: String) -> Result<DatabaseGameStatus, String> {
|
|||||||
Ok(status)
|
Ok(status)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fetch_game_verion_options_logic(
|
fn fetch_game_verion_options_logic<'a>(
|
||||||
game_id: String,
|
game_id: String,
|
||||||
|
state: tauri::State<'_, Mutex<AppState>>,
|
||||||
) -> Result<Vec<GameVersionOption>, RemoteAccessError> {
|
) -> Result<Vec<GameVersionOption>, RemoteAccessError> {
|
||||||
let base_url = DB.fetch_base_url();
|
let base_url = DB.fetch_base_url();
|
||||||
|
|
||||||
@@ -222,12 +224,27 @@ fn fetch_game_verion_options_logic(
|
|||||||
|
|
||||||
let data = response.json::<Vec<GameVersionOption>>()?;
|
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)
|
Ok(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn fetch_game_verion_options(game_id: String) -> Result<Vec<GameVersionOption>, String> {
|
pub fn fetch_game_verion_options<'a>(
|
||||||
fetch_game_verion_options_logic(game_id).map_err(|e| e.to_string())
|
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(
|
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())
|
|
||||||
}
|
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
pub mod process_manager;
|
||||||
@@ -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