diff --git a/babylonia-terminal-sdk/src/components/dxvk_component.rs b/babylonia-terminal-sdk/src/components/dxvk_component.rs new file mode 100644 index 0000000..a134c77 --- /dev/null +++ b/babylonia-terminal-sdk/src/components/dxvk_component.rs @@ -0,0 +1,103 @@ +use std::{ + fs::{remove_dir, remove_file, rename, File}, + path::PathBuf, +}; + +use downloader::{Download, Downloader}; +use flate2::read::GzDecoder; +use tar::Archive; +use tokio::fs::remove_dir_all; +use wincompatlib::{dxvk::InstallParams, wine::Wine}; + +use crate::utils::github_requester::GithubRequester; + +use super::component_downloader::ComponentDownloader; + +pub struct DXVKComponent<'a> { + wine: &'a Wine, + path: PathBuf, +} + +impl<'a> DXVKComponent<'a> { + pub fn from_wine<'b: 'a>(wine: &'b Wine, path: PathBuf) -> Self { + DXVKComponent { wine, path } + } +} + +impl<'a> GithubRequester for DXVKComponent<'a> {} + +impl<'a> ComponentDownloader for DXVKComponent<'a> { + async fn install( + &self, + progress: Option>, + ) -> anyhow::Result<()> { + let dir = self + .path + .parent() + .expect("Failed to get parent folder for DXVK") + .to_path_buf(); + let file_output = Self::download(&dir, progress).await?; + + Self::uncompress(file_output.clone(), self.path.clone()).await?; + + self.wine + .install_dxvk(self.path.clone(), InstallParams::default()) + .expect("Failed to installed DXVK"); + + //clean the directory + remove_dir_all(self.path.clone()) + .await + .expect("Failed to delete all the dxvk files"); + + Ok(()) + } + + async fn download( + output_dir: &std::path::PathBuf, + progress: Option>, + ) -> anyhow::Result { + let releases = Self::get_latest_github_release("doitsujin", "dxvk").await?; + + let asset = releases[0] + .assets + .first() + .expect("Asset not found in the github release"); + + let mut downloader = Downloader::builder() + .download_folder(output_dir) + .parallel_requests(1) + .build()?; + let mut dl = downloader::Download::new(&asset.browser_download_url); + if let Some(p) = progress { + dl = dl.progress(p); + } + + let _result = downloader.async_download(&[dl]).await?; + let file_location = output_dir.join(asset.name.clone()); + + Ok(file_location) + } + + async fn uncompress( + file: std::path::PathBuf, + new_directory_name: std::path::PathBuf, + ) -> anyhow::Result<()> { + tokio::task::spawn_blocking(move || { + let tar_gz = File::open(file.clone()).unwrap(); + let tar = GzDecoder::new(tar_gz); + let mut archive = Archive::new(tar); + archive + .unpack(new_directory_name.parent().unwrap()) + .unwrap(); + remove_file(file.clone()).unwrap(); + rename( + file.to_str().unwrap().strip_suffix(".tar.gz").unwrap(), + new_directory_name, + ) + .unwrap() + }) + .await?; + + Ok(()) + } +} diff --git a/babylonia-terminal-sdk/src/components/mod.rs b/babylonia-terminal-sdk/src/components/mod.rs index 6f08637..c60d39f 100644 --- a/babylonia-terminal-sdk/src/components/mod.rs +++ b/babylonia-terminal-sdk/src/components/mod.rs @@ -1,2 +1,4 @@ pub(crate) mod component_downloader; +pub(crate) mod dxvk_component; +pub(crate) mod pgr_component; pub(crate) mod wine_component; diff --git a/babylonia-terminal-sdk/src/game_manager.rs b/babylonia-terminal-sdk/src/game_manager.rs index 6013c24..057e699 100644 --- a/babylonia-terminal-sdk/src/game_manager.rs +++ b/babylonia-terminal-sdk/src/game_manager.rs @@ -14,7 +14,11 @@ use wincompatlib::{prelude::*, wine::bundle::proton}; use xz::read::XzDecoder; use crate::{ - components::{component_downloader::ComponentDownloader, wine_component::WineComponent}, + components::{ + component_downloader::ComponentDownloader, + dxvk_component::{self, DXVKComponent}, + wine_component::WineComponent, + }, components_downloader::ComponentsDownloader, game_state::GameState, }; @@ -55,30 +59,8 @@ impl GameManager { where P: Reporter + 'static, { - let file_output = ComponentsDownloader::download_latest_dxvk(&config_dir, progress) - .await - .expect("failed to download dxvk"); - - let file_to_uncompress = file_output.clone(); - tokio::task::spawn_blocking(move || { - let tar_gz = File::open(file_to_uncompress.clone()).unwrap(); - let tar = GzDecoder::new(tar_gz); - let mut archive = Archive::new(tar); - archive.unpack(config_dir).unwrap(); - remove_file(file_to_uncompress.clone()).unwrap(); - }) - .await - .unwrap(); - - wine.install_dxvk( - file_output - .to_str() - .unwrap() - .strip_suffix(".tar.gz") - .unwrap(), - InstallParams::default(), - ) - .expect("failed to installed DXVK"); + let dxvk_component = DXVKComponent::from_wine(wine, config_dir.join("dxvk")); + dxvk_component.install(progress).await?; let mut config = GameState::get_config().await?; config.is_dxvk_installed = true;