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

View File

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

View File

@ -1,24 +1,29 @@
use std::{
env::home_dir,
fs::{create_dir, remove_file, rename, File},
path::PathBuf,
str::FromStr,
sync::Arc,
};
use downloader::{progress::Reporter, Downloader};
use flate2::read::GzDecoder;
use log::debug;
use tar::Archive;
use wincompatlib::wine::ext::WineBootExt;
use wincompatlib::wine::{bundle::proton::Proton, ext::WineBootExt};
use xz::read::XzDecoder;
use super::component_downloader::ComponentDownloader;
use crate::{game_state::GameState, utils::github_requester::GithubRequester};
pub struct WineComponent {
#[derive(Debug, PartialEq, Eq)]
pub struct ProtonComponent {
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<()> {
let file_output = Self::download(
&self
@ -38,7 +43,8 @@ impl ComponentDownloader for WineComponent {
output_dir: &PathBuf,
progress: Option<Arc<P>>,
) -> 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]
.assets
@ -64,18 +70,14 @@ impl ComponentDownloader for WineComponent {
async fn uncompress(file: PathBuf, new_directory_name: PathBuf) -> anyhow::Result<()> {
tokio::task::spawn_blocking(move || {
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);
archive
.unpack(new_directory_name.parent().unwrap())
.unwrap();
remove_file(file.clone()).unwrap();
rename(
file.to_str()
.unwrap()
.replace("wine-", "")
.strip_suffix(".tar.xz")
.unwrap(),
file.to_str().unwrap().strip_suffix(".tar.gz").unwrap(),
new_directory_name,
)
.unwrap();
@ -87,21 +89,31 @@ impl ComponentDownloader for WineComponent {
}
}
impl WineComponent {
impl ProtonComponent {
pub fn new(path: PathBuf) -> Self {
WineComponent { path }
ProtonComponent { path }
}
pub fn init_wine(&self) -> wincompatlib::prelude::Wine {
let wine_path = self.path.join("files/bin/wine64");
let wine_prefix = self.path.parent().unwrap().join("data");
if !wine_prefix.exists() {
create_dir(wine_prefix.clone()).unwrap()
pub fn init_proton(&self) -> Result<wincompatlib::prelude::Proton, String> {
//let wine_path = self.path.join("files/bin/wine64");
//let wine_prefix = self.path.parent().unwrap().join("data");
//if !wine_prefix.exists() {
// 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);
wine.update_prefix(Some(wine_prefix)).unwrap();
wine
Ok(proton)
}
}

View File

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