change wine by proton

This commit is contained in:
ALEZ-DEV 2024-05-02 20:17:01 +02:00
parent e06b93e458
commit 9612771024
4 changed files with 80 additions and 60 deletions

View File

@ -1,7 +1,7 @@
use babylonia_terminal_sdk::{ use babylonia_terminal_sdk::{
components::wine_component::WineComponent, game_manager::GameManager, game_state::GameState, components::proton_component::ProtonComponent, game_manager::GameManager, game_state::GameState,
}; };
use log::{info, LevelFilter}; use log::{debug, info, LevelFilter};
use simple_logger::SimpleLogger; use simple_logger::SimpleLogger;
use wincompatlib::prelude::*; use wincompatlib::prelude::*;
@ -21,23 +21,27 @@ async fn main() {
.init() .init()
.unwrap(); .unwrap();
let mut wine_component: Option<WineComponent> = None; let mut proton_component: Option<ProtonComponent> = None;
let mut wine: Option<Wine> = None; let mut proton: Option<Proton> = None;
loop { loop {
let state = GameState::get_current_state().await; let state = GameState::get_current_state().await;
if let (Some(component), None) = (&wine_component, &wine) { if GameState::get_current_state().await != GameState::WineNotInstalled
wine = Some(component.init_wine()); && proton_component == None
} else if GameState::get_current_state().await != GameState::WineNotInstalled { {
let wine_component = WineComponent::new(GameState::get_config_directory().join("wine")); let proton_component =
wine = Some(wine_component.init_wine()); ProtonComponent::new(GameState::get_config_directory().join("wine"));
match proton_component.init_proton() {
Ok(p) => proton = Some(p),
Err(err) => panic!("{}", err),
};
} }
match state { match state {
GameState::WineNotInstalled => { GameState::WineNotInstalled => {
info!("Wine not installed, installing it..."); info!("Wine not installed, installing it...");
wine_component = Some( proton_component = Some(
GameManager::install_wine( GameManager::install_wine(
GameState::get_config_directory(), GameState::get_config_directory(),
Some(DownloadReporter::create(false)), Some(DownloadReporter::create(false)),
@ -50,7 +54,7 @@ async fn main() {
GameState::DXVKNotInstalled => { GameState::DXVKNotInstalled => {
info!("DXVK not installed, installing it..."); info!("DXVK not installed, installing it...");
GameManager::install_dxvk( GameManager::install_dxvk(
&wine.clone().unwrap(), &proton.clone().unwrap(),
GameState::get_config_directory(), GameState::get_config_directory(),
Some(DownloadReporter::create(false)), Some(DownloadReporter::create(false)),
) )
@ -60,14 +64,17 @@ async fn main() {
} }
GameState::FontNotInstalled => { GameState::FontNotInstalled => {
info!("Fonts not installed, installing it..."); info!("Fonts not installed, installing it...");
GameManager::install_font(&wine.clone().unwrap(), DownloadReporter::create(false)) GameManager::install_font(
&proton.clone().unwrap(),
DownloadReporter::create(false),
)
.await .await
.expect("Failed to install fonts"); .expect("Failed to install fonts");
info!("Fonts installed"); info!("Fonts installed");
} }
GameState::DependecieNotInstalled => { GameState::DependecieNotInstalled => {
info!("Dependecies not installed, installing it..."); info!("Dependecies not installed, installing it...");
GameManager::install_dependecies(&wine.clone().unwrap()) GameManager::install_dependecies(&proton.clone().unwrap())
.await .await
.expect("Failed to install dependecies"); .expect("Failed to install dependecies");
info!("Dependecies installed"); info!("Dependecies installed");
@ -90,8 +97,9 @@ async fn main() {
} }
info!("Starting game..."); info!("Starting game...");
debug!("{:?}", proton);
GameManager::start_game( GameManager::start_game(
&wine.unwrap(), &proton.unwrap(),
GameState::get_config_directory().join("PGR"), GameState::get_config_directory().join("PGR"),
) )
.await; .await;

View File

@ -1,4 +1,4 @@
pub mod component_downloader; pub mod component_downloader;
pub mod dxvk_component; pub mod dxvk_component;
pub mod game_component; pub mod game_component;
pub mod wine_component; pub mod proton_component;

View File

@ -1,24 +1,29 @@
use std::{ use std::{
env::home_dir,
fs::{create_dir, remove_file, rename, File}, fs::{create_dir, remove_file, rename, File},
path::PathBuf, path::PathBuf,
str::FromStr,
sync::Arc, sync::Arc,
}; };
use downloader::{progress::Reporter, Downloader}; use downloader::{progress::Reporter, Downloader};
use flate2::read::GzDecoder;
use log::debug;
use tar::Archive; use tar::Archive;
use wincompatlib::wine::ext::WineBootExt; use wincompatlib::wine::{bundle::proton::Proton, ext::WineBootExt};
use xz::read::XzDecoder; use xz::read::XzDecoder;
use super::component_downloader::ComponentDownloader; use super::component_downloader::ComponentDownloader;
use crate::{game_state::GameState, utils::github_requester::GithubRequester}; use crate::{game_state::GameState, utils::github_requester::GithubRequester};
pub struct WineComponent { #[derive(Debug, PartialEq, Eq)]
pub struct ProtonComponent {
path: PathBuf, path: PathBuf,
} }
impl GithubRequester for WineComponent {} impl GithubRequester for ProtonComponent {}
impl ComponentDownloader for WineComponent { impl ComponentDownloader for ProtonComponent {
async fn install<P: Reporter + 'static>(&self, progress: Option<Arc<P>>) -> anyhow::Result<()> { async fn install<P: Reporter + 'static>(&self, progress: Option<Arc<P>>) -> anyhow::Result<()> {
let file_output = Self::download( let file_output = Self::download(
&self &self
@ -38,7 +43,8 @@ impl ComponentDownloader for WineComponent {
output_dir: &PathBuf, output_dir: &PathBuf,
progress: Option<Arc<P>>, progress: Option<Arc<P>>,
) -> anyhow::Result<PathBuf> { ) -> anyhow::Result<PathBuf> {
let release = Self::get_latest_github_release("GloriousEggroll", "wine-ge-custom").await?; let release =
Self::get_latest_github_release("GloriousEggroll", "proton-ge-custom").await?;
let asset = release[0] let asset = release[0]
.assets .assets
@ -64,18 +70,14 @@ impl ComponentDownloader for WineComponent {
async fn uncompress(file: PathBuf, new_directory_name: PathBuf) -> anyhow::Result<()> { async fn uncompress(file: PathBuf, new_directory_name: PathBuf) -> anyhow::Result<()> {
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
let tar_xz = File::open(file.clone()).unwrap(); let tar_xz = File::open(file.clone()).unwrap();
let tar = XzDecoder::new(tar_xz); let tar = GzDecoder::new(tar_xz);
let mut archive = Archive::new(tar); let mut archive = Archive::new(tar);
archive archive
.unpack(new_directory_name.parent().unwrap()) .unpack(new_directory_name.parent().unwrap())
.unwrap(); .unwrap();
remove_file(file.clone()).unwrap(); remove_file(file.clone()).unwrap();
rename( rename(
file.to_str() file.to_str().unwrap().strip_suffix(".tar.gz").unwrap(),
.unwrap()
.replace("wine-", "")
.strip_suffix(".tar.xz")
.unwrap(),
new_directory_name, new_directory_name,
) )
.unwrap(); .unwrap();
@ -87,21 +89,31 @@ impl ComponentDownloader for WineComponent {
} }
} }
impl WineComponent { impl ProtonComponent {
pub fn new(path: PathBuf) -> Self { pub fn new(path: PathBuf) -> Self {
WineComponent { path } ProtonComponent { path }
} }
pub fn init_wine(&self) -> wincompatlib::prelude::Wine { pub fn init_proton(&self) -> Result<wincompatlib::prelude::Proton, String> {
let wine_path = self.path.join("files/bin/wine64"); //let wine_path = self.path.join("files/bin/wine64");
let wine_prefix = self.path.parent().unwrap().join("data"); //let wine_prefix = self.path.parent().unwrap().join("data");
if !wine_prefix.exists() { //if !wine_prefix.exists() {
create_dir(wine_prefix.clone()).unwrap() // create_dir(wine_prefix.clone()).unwrap()
//}
//let wine = wincompatlib::prelude::Wine::from_binary(wine_path);
//wine.update_prefix(Some(wine_prefix)).unwrap();
let prefix = self.path.parent().unwrap().join("data");
let steam_location = dirs::home_dir().unwrap().join(".steam/steam");
if !steam_location.exists() {
debug!("Can't find steam installation");
return Err(String::from_str("We can't find your steam installation, please install steam in '~/.steam/steam' or specify your steam installation").unwrap());
} }
let mut proton =
wincompatlib::prelude::Proton::new(self.path.clone(), Some(prefix.clone()));
proton.steam_client_path = Some(steam_location);
proton.init_prefix(Some(prefix)).unwrap();
let wine = wincompatlib::prelude::Wine::from_binary(wine_path); Ok(proton)
wine.update_prefix(Some(wine_prefix)).unwrap();
wine
} }
} }

View File

@ -20,7 +20,7 @@ use crate::{
component_downloader::ComponentDownloader, component_downloader::ComponentDownloader,
dxvk_component::{self, DXVKComponent}, dxvk_component::{self, DXVKComponent},
game_component::GameComponent, game_component::GameComponent,
wine_component::WineComponent, proton_component::ProtonComponent,
}, },
components_downloader::ComponentsDownloader, components_downloader::ComponentsDownloader,
game_state::GameState, game_state::GameState,
@ -32,11 +32,11 @@ impl GameManager {
pub async fn install_wine<P>( pub async fn install_wine<P>(
config_dir: PathBuf, config_dir: PathBuf,
progress: Option<Arc<P>>, progress: Option<Arc<P>>,
) -> anyhow::Result<WineComponent> ) -> anyhow::Result<ProtonComponent>
where where
P: Reporter + 'static, P: Reporter + 'static,
{ {
let wine_component = WineComponent::new(config_dir.join("wine")); let wine_component = ProtonComponent::new(config_dir.join("wine"));
wine_component.install(progress).await?; wine_component.install(progress).await?;
@ -55,14 +55,14 @@ impl GameManager {
} }
pub async fn install_dxvk<P>( pub async fn install_dxvk<P>(
wine: &Wine, proton: &Proton,
config_dir: PathBuf, config_dir: PathBuf,
progress: Option<Arc<P>>, progress: Option<Arc<P>>,
) -> anyhow::Result<()> ) -> anyhow::Result<()>
where where
P: Reporter + 'static, P: Reporter + 'static,
{ {
let dxvk_component = DXVKComponent::from_wine(wine, config_dir.join("dxvk")); let dxvk_component = DXVKComponent::from_wine(proton.wine(), config_dir.join("dxvk"));
dxvk_component.install(progress).await?; dxvk_component.install(progress).await?;
let mut config = GameState::get_config().await?; let mut config = GameState::get_config().await?;
@ -72,41 +72,41 @@ impl GameManager {
Ok(()) Ok(())
} }
pub async fn install_font<P>(wine: &Wine, progress: Arc<P>) -> anyhow::Result<()> pub async fn install_font<P>(proton: &Proton, progress: Arc<P>) -> anyhow::Result<()>
where where
P: Reporter + 'static, P: Reporter + 'static,
{ {
progress.setup(Some(10), ""); progress.setup(Some(10), "");
progress.progress(0); progress.progress(0);
wine.install_font(Font::Arial)?; proton.install_font(Font::Arial)?;
progress.progress(1); progress.progress(1);
wine.install_font(Font::Andale)?; proton.install_font(Font::Andale)?;
progress.progress(2); progress.progress(2);
wine.install_font(Font::Courier)?; proton.install_font(Font::Courier)?;
progress.progress(3); progress.progress(3);
wine.install_font(Font::ComicSans)?; proton.install_font(Font::ComicSans)?;
progress.progress(4); progress.progress(4);
wine.install_font(Font::Georgia)?; proton.install_font(Font::Georgia)?;
progress.progress(5); progress.progress(5);
wine.install_font(Font::Impact)?; proton.install_font(Font::Impact)?;
progress.progress(6); progress.progress(6);
wine.install_font(Font::Times)?; proton.install_font(Font::Times)?;
progress.progress(7); progress.progress(7);
wine.install_font(Font::Trebuchet)?; proton.install_font(Font::Trebuchet)?;
progress.progress(8); progress.progress(8);
wine.install_font(Font::Verdana)?; proton.install_font(Font::Verdana)?;
progress.progress(9); progress.progress(9);
wine.install_font(Font::Webdings)?; proton.install_font(Font::Webdings)?;
progress.progress(10); progress.progress(10);
let mut config = GameState::get_config().await?; let mut config = GameState::get_config().await?;
@ -116,8 +116,8 @@ impl GameManager {
Ok(()) Ok(())
} }
pub async fn install_dependecies(wine: &Wine) -> anyhow::Result<()> { pub async fn install_dependecies(proton: &Proton) -> anyhow::Result<()> {
let winetricks = Winetricks::from_wine("winetricks", wine); let winetricks = Winetricks::from_wine("winetricks", proton.wine());
winetricks.install("corefonts")?; winetricks.install("corefonts")?;
winetricks.install("vcrun2022")?; winetricks.install("vcrun2022")?;
@ -144,9 +144,9 @@ impl GameManager {
Ok(()) Ok(())
} }
pub async fn start_game(wine: &Wine, game_dir: PathBuf) { pub async fn start_game(proton: &Proton, game_dir: PathBuf) {
debug!("Wine version : {:?}", wine.version().unwrap()); debug!("Wine version : {:?}", proton.wine().version().unwrap());
let mut child = wine.run(game_dir.join("PGR.exe")).unwrap(); let mut child = proton.run(game_dir.join("PGR.exe")).unwrap();
tokio::task::spawn_blocking(move || { tokio::task::spawn_blocking(move || {
let mut stdout = BufReader::new(child.stdout.as_mut().unwrap()); let mut stdout = BufReader::new(child.stdout.as_mut().unwrap());