diff --git a/core/src/constants.rs b/core/src/constants.rs index 4c67c0b3..efae1cdd 100644 --- a/core/src/constants.rs +++ b/core/src/constants.rs @@ -1,5 +1,5 @@ // Authentication and HTTP (TODO: env?) -pub const APP_CONFIG_DIR: &str = "org.polyfrost.onelauncher"; +pub const APP_CONFIG_DIR: &str = "org.polyfrost.launcher"; pub const USER_AGENT: &str = "OneLauncher/1.0.0 (polyfrost.org)"; // Microsoft Authentication diff --git a/core/src/game/client.rs b/core/src/game/client.rs index 5099fc02..6e5f61ac 100644 --- a/core/src/game/client.rs +++ b/core/src/game/client.rs @@ -4,6 +4,7 @@ use anyhow::anyhow; use async_trait::async_trait; use chrono::{DateTime, Local}; use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use thiserror::Error; use uuid::Uuid; use crate::{utils::dirs, PolyResult}; @@ -51,13 +52,14 @@ impl ClientType { } } +pub fn get_impl<'a>(client: &'a ClientType, instance: &'a Instance, manifest: &'a Manifest) -> Box + 'a> { + Box::new(match client { + ClientType::Vanilla(_) => vanilla::VanillaClient::new(instance, manifest) + }) +} + #[async_trait] pub trait ClientTrait<'a>: Send + Sync { - fn get_impl(client: &'a ClientType, instance: &'a Instance, manifest: &'a Manifest) -> Box + 'a> where Self: Sized { - Box::new(match client { - ClientType::Vanilla(_) => vanilla::VanillaClient::new(instance, manifest) - }) - } fn new(instance: &'a Instance, manifest: &'a Manifest) -> Self where Self: Sized; @@ -103,6 +105,14 @@ macro_rules! impl_game_client { }; } +#[derive(Debug, Error)] +pub enum ClientManagerError { + #[error("Instance not found")] + InstanceNotFound, + #[error("Manifest not found")] + ManifestNotFound, +} + pub struct ClientManager { instances: HashMap, manifests: HashMap, @@ -124,6 +134,13 @@ impl ClientManager { }) } + pub fn get_impl_uuid<'a>(&'a self, uuid: Uuid) -> PolyResult + 'a>> { + let instance = self.get_instance(uuid)?; + let manifest = self.get_manifest(uuid)?; + + Ok(get_impl(&instance.client, &instance, &manifest)) + } + pub fn get_instances(&self) -> Vec<&Instance> { self.instances.values().collect() } @@ -132,20 +149,20 @@ impl ClientManager { self.instances.values().cloned().collect() } - pub fn get_instance(&self, uuid: Uuid) -> Option<&Instance> { - self.instances.get(&uuid) + pub fn get_instance(&self, uuid: Uuid) -> PolyResult<&Instance> { + self.instances.get(&uuid).ok_or(ClientManagerError::InstanceNotFound.into()) } - pub fn get_instance_mut(&mut self, uuid: Uuid) -> Option<&mut Instance> { - self.instances.get_mut(&uuid) + pub fn get_instance_mut(&mut self, uuid: Uuid) -> PolyResult<&mut Instance> { + self.instances.get_mut(&uuid).ok_or(ClientManagerError::InstanceNotFound.into()) } - pub fn get_manifest(&self, uuid: Uuid) -> Option<&Manifest> { - self.manifests.get(&uuid) + pub fn get_manifest(&self, uuid: Uuid) -> PolyResult<&Manifest> { + self.manifests.get(&uuid).ok_or(ClientManagerError::ManifestNotFound.into()) } - pub fn get_manifest_mut(&mut self, uuid: Uuid) -> Option<&mut Manifest> { - self.manifests.get_mut(&uuid) + pub fn get_manifest_mut(&mut self, uuid: Uuid) -> PolyResult<&mut Manifest> { + self.manifests.get_mut(&uuid).ok_or(ClientManagerError::ManifestNotFound.into()) } pub async fn create_instance(&mut self, diff --git a/core/src/lib.rs b/core/src/lib.rs index 635e359f..88e2fbf9 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -59,6 +59,16 @@ pub enum PolyError { /// Wrapper around [`utils::dirs::DirectoryError`] to handle directory errors. #[error("failed to get directory: {0}")] DirectoryError(#[from] utils::dirs::DirectoryError), + + /// Wrapper around [`game::client::ClientManagerError`] to handle directory errors. + #[error("failed to manage clients: {0}")] + ClientManagerError(#[from] game::client::ClientManagerError), +} + +impl From for String { + fn from(value: PolyError) -> Self { + value.to_string() + } } /// Alias for a [`Result`] with the error type [`PolyError`]. diff --git a/src-tauri/src/launcher_core/game.rs b/src-tauri/src/launcher_core/game.rs index 8cd51e38..601ea2b8 100644 --- a/src-tauri/src/launcher_core/game.rs +++ b/src-tauri/src/launcher_core/game.rs @@ -15,15 +15,24 @@ pub async fn create_instance( client: ClientType ) -> Result { let manager = &mut state.lock().await.client_manager; - - manager.create_instance(name, version, cover, group, client).await.or_else(|e| { - Err(e.to_string()) - }) + let uuid = manager.create_instance(name, version, cover, group, client).await?; + Ok(uuid) } #[tauri::command] -pub async fn get_instances(state: State<'_, Mutex>) -> Result, String> { +pub async fn get_instances( + state: State<'_, Mutex> +) -> Result, String> { let manager = &mut state.lock().await.client_manager; - Ok(manager.get_instances_owned()) +} + +#[tauri::command] +pub async fn get_instance( + state: State<'_, Mutex>, + uuid: Uuid +) -> Result { + let manager = &mut state.lock().await.client_manager; + let instance = manager.get_instance(uuid)?; + Ok(instance.clone()) } \ No newline at end of file diff --git a/src-tauri/src/launcher_core/mod.rs b/src-tauri/src/launcher_core/mod.rs index e87b1081..c5f2b6f4 100644 --- a/src-tauri/src/launcher_core/mod.rs +++ b/src-tauri/src/launcher_core/mod.rs @@ -25,6 +25,7 @@ pub fn init() -> TauriPlugin { auth::login_msa, game::create_instance, game::get_instances, + game::get_instance, ]) .build() } diff --git a/src/ui/pages/Browser.tsx b/src/ui/pages/Browser.tsx index 3edf2bf1..33747cfe 100644 --- a/src/ui/pages/Browser.tsx +++ b/src/ui/pages/Browser.tsx @@ -8,9 +8,11 @@ function BrowserPage() {