From 7ac3935ab122701a805ca0b1b5797ea679e4e0a1 Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Sun, 25 Sep 2022 21:37:30 +0200 Subject: [PATCH] Added partial support of wincompatlib --- Cargo.lock | 10 +++++++ Cargo.toml | 1 + src/lib/dxvk.rs | 60 ++++++++------------------------------ src/lib/launcher/states.rs | 5 ++-- src/lib/mod.rs | 1 - src/lib/wine.rs | 19 ++++++++++-- src/lib/wine_prefix.rs | 39 ------------------------- src/ui/first_run/mod.rs | 12 ++++++-- src/ui/main.rs | 18 +++++++----- 9 files changed, 62 insertions(+), 103 deletions(-) delete mode 100644 src/lib/wine_prefix.rs diff --git a/Cargo.lock b/Cargo.lock index 85be20d..1fed18b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -66,6 +66,7 @@ dependencies = [ "serde", "serde_json", "wait_not_await", + "wincompatlib", ] [[package]] @@ -2300,6 +2301,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "wincompatlib" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0fb138cb8c6312731e7385e4500a2491be768ff4c8cfc04544dcc9227533f250" +dependencies = [ + "regex", +] + [[package]] name = "windows" version = "0.37.0" diff --git a/Cargo.toml b/Cargo.toml index 04c4ae8..185d283 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ adw = { package = "libadwaita", version = "0.2.0-alpha.3", features = ["v1_2"] } rfd = { version = "0.10", features = ["xdg-portal"], default-features = false } anime-game-core = { path = "anime-game-core", features = ["all", "static", "genshin"] } +wincompatlib = { version = "0.1.0", features = ["dxvk"] } serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/src/lib/dxvk.rs b/src/lib/dxvk.rs index 8ee31ae..3c298c7 100644 --- a/src/lib/dxvk.rs +++ b/src/lib/dxvk.rs @@ -1,10 +1,11 @@ use serde::{Serialize, Deserialize}; -use std::io::{Error, ErrorKind}; -use std::process::{Command, Output}; +use std::process::Output; +use std::path::PathBuf; use lazy_static::lazy_static; -use regex::Regex; + +use wincompatlib::prelude::*; use crate::lib::config; @@ -94,50 +95,13 @@ impl Version { None => (String::from("wine64"), String::from("wineserver"), String::from("wineboot")) }; - let mut apply_script = std::fs::read_to_string(&apply_path)?; - - lazy_static! { - static ref WINE: Regex = Regex::new("wine=\".*\"").unwrap(); - static ref WINE64: Regex = Regex::new("wine64=\".*\"").unwrap(); - static ref WINEBOOT: Regex = Regex::new("wineboot=\".*\"").unwrap(); - } - - // Update wine paths - apply_script = WINE.replace_all(&apply_script, &format!("wine=\"{}\"", &wine_path)).to_string(); - apply_script = WINE64.replace_all(&apply_script, &format!("wine64=\"{}\"", &wine_path)).to_string(); - apply_script = WINEBOOT.replace_all(&apply_script, &format!("wineboot=\"{}\"", &wineboot_path)).to_string(); - - // Use wine64 to update wine prefix instead of running wineboot - // so we can get rid of 32bit support - apply_script = apply_script.replace("$wineboot -u", "\"$wine64\" -u"); - - // Fix issues related to spaces in paths to the runners folder - apply_script = apply_script.replace("which $wineboot", "which \"$wineboot\""); - apply_script = apply_script.replace("$wine --version", "\"$wine\" --version"); - apply_script = apply_script.replace("$wine64 winepath", "\"$wine64\" winepath"); - apply_script = apply_script.replace("$wine winepath", "\"$wine\" winepath"); - apply_script = apply_script.replace("$wine reg", "\"$wine\" reg"); - - // Old GE builds return specific --version output which can break - // DXVK installation script - apply_script = apply_script.replace("grep wine", "grep \"wine\\|GE\""); - - std::fs::write(&apply_path, apply_script)?; - - let output = Command::new("bash") - .arg(&apply_path) - .arg("install") - .env("WINEARCH", "win64") - .env("WINESERVER", wineserver_path) - .env("WINEPREFIX", prefix_path.to_string()) - .output()?; - - if output.status.success() { - Ok(output) - } - - else { - Err(Error::new(ErrorKind::Other, String::from_utf8_lossy(&output.stderr))) - } + Dxvk::install( + PathBuf::from(apply_path), + PathBuf::from(prefix_path.to_string()), + PathBuf::from(&wine_path), + PathBuf::from(wine_path), + PathBuf::from(wineboot_path), + PathBuf::from(wineserver_path) + ) } } diff --git a/src/lib/launcher/states.rs b/src/lib/launcher/states.rs index 7d2e218..f6b0b4e 100644 --- a/src/lib/launcher/states.rs +++ b/src/lib/launcher/states.rs @@ -1,9 +1,10 @@ +use std::path::PathBuf; + use anime_game_core::prelude::*; use anime_game_core::genshin::prelude::*; use crate::lib::consts; use crate::lib::config; -use crate::lib::wine_prefix::WinePrefix; #[derive(Debug, Clone)] pub enum LauncherState { @@ -55,7 +56,7 @@ impl LauncherState { } // Check prefix existence - if !WinePrefix::exists_in(&config.game.wine.prefix) { + if !PathBuf::from(&config.game.wine.prefix).join("drive_c").exists() { return Ok(Self::PrefixNotExists); } diff --git a/src/lib/mod.rs b/src/lib/mod.rs index 93e0269..15b66fd 100644 --- a/src/lib/mod.rs +++ b/src/lib/mod.rs @@ -3,7 +3,6 @@ pub mod config; pub mod game; pub mod dxvk; pub mod wine; -pub mod wine_prefix; pub mod launcher; pub mod prettify_bytes; pub mod fps_unlocker; diff --git a/src/lib/wine.rs b/src/lib/wine.rs index 8fb1e57..db67078 100644 --- a/src/lib/wine.rs +++ b/src/lib/wine.rs @@ -1,5 +1,9 @@ +use std::path::PathBuf; + use serde::{Serialize, Deserialize}; +use wincompatlib::prelude::*; + lazy_static::lazy_static! { static ref GROUPS: Vec = vec![ Group { @@ -79,8 +83,19 @@ impl Version { Ok(List::get()[0].versions[0].clone()) } - pub fn is_downloaded_in(&self, folder: T) -> bool { - std::path::Path::new(&format!("{}/{}", folder.to_string(), self.name)).exists() + pub fn is_downloaded_in>(&self, folder: T) -> bool { + folder.into().join(&self.name).exists() + } + + pub fn to_wine(&self) -> Wine { + Wine::new( + &self.files.wine64, + None, + Some(WineArch::Win64), + Some(&self.files.wineboot), + Some(&self.files.wineserver), + WineLoader::Current + ) } } diff --git a/src/lib/wine_prefix.rs b/src/lib/wine_prefix.rs deleted file mode 100644 index ba5e7d2..0000000 --- a/src/lib/wine_prefix.rs +++ /dev/null @@ -1,39 +0,0 @@ -use std::path::Path; -use std::process::{Command, Output}; - -#[derive(Debug, Clone)] -pub struct WinePrefix { - pub path: String -} - -impl WinePrefix { - pub fn new(path: T) -> Self { - Self { path: path.to_string() } - } - - pub fn exists(&self) -> bool { - Self::exists_in(&self.path) - } - - pub fn exists_in(path: T) -> bool { - Path::new(&format!("{}/drive_c", path.to_string())).exists() - } - - fn wine(&self, wine_binary: T, command: &str) -> std::io::Result { - let mut wine_command = Command::new(wine_binary.to_string()); - - wine_command.env("WINEARCH", "win64") - .env("WINEPREFIX", &self.path) - .arg(command); - - Ok(wine_command.output()?) - } - - pub fn update(&self, runners_folder: T, runner: super::wine::Version) -> std::io::Result { - self.update_with(format!("{}/{}/{}", runners_folder.to_string(), runner.name, runner.files.wine64)) - } - - pub fn update_with(&self, wine_binary: T) -> std::io::Result { - self.wine(wine_binary, "-u") - } -} diff --git a/src/ui/first_run/mod.rs b/src/ui/first_run/mod.rs index bb58fdf..650f2b0 100644 --- a/src/ui/first_run/mod.rs +++ b/src/ui/first_run/mod.rs @@ -10,6 +10,8 @@ use std::path::PathBuf; use anime_game_core::prelude::*; +use wincompatlib::prelude::*; + mod welcome; mod dependencies; mod tos_warning; @@ -23,7 +25,6 @@ use crate::ui::traits::prelude::*; use crate::ui::components::progress_bar::*; use crate::lib; -use crate::lib::wine_prefix::WinePrefix; use crate::lib::config; /// This structure is used to describe widgets used in application @@ -303,7 +304,6 @@ impl App { ProgressUpdateResult::Finished => { let mut config = config::get().unwrap(); - let prefix = WinePrefix::new(&config.game.wine.prefix); // Update wine config if let Some(wine_version) = &wine_version { @@ -318,7 +318,13 @@ impl App { let sender_dxvk = sender_dxvk.clone(); std::thread::spawn(move || { - match prefix.update_with(config.try_get_wine_executable().expect("None of wine builds are available")) { + let wine = config.try_get_wine_executable() + .expect("None of wine builds are available"); + + let wine = Wine::from_binary(wine) + .with_arch(WineArch::Win64); + + match wine.update_prefix(&config.game.wine.prefix) { Ok(output) => { println!("Wine prefix created:\n\n{}", String::from_utf8_lossy(&output.stdout)); diff --git a/src/ui/main.rs b/src/ui/main.rs index a98ac84..87d7985 100644 --- a/src/ui/main.rs +++ b/src/ui/main.rs @@ -14,6 +14,8 @@ use wait_not_await::Await; use anime_game_core::prelude::*; use anime_game_core::genshin::prelude::*; +use wincompatlib::prelude::*; + use crate::ui::*; use super::preferences::PreferencesStack; @@ -28,7 +30,6 @@ use crate::lib::wine::{ Version as WineVersion, List as WineList }; -use crate::lib::wine_prefix::WinePrefix; /// This structure is used to describe widgets used in application /// @@ -496,16 +497,17 @@ impl App { } LauncherState::PrefixNotExists => { - let prefix = WinePrefix::new(&config.game.wine.prefix); - - match config.try_get_selected_wine_info() { + match config.try_get_wine_executable() { Some(wine) => { let this = this.clone(); std::thread::spawn(move || { this.widgets.launch_game.set_sensitive(false); - if let Err(err) = prefix.update(&config.game.wine.builds, wine) { + let wine = Wine::from_binary(wine) + .with_arch(WineArch::Win64); + + if let Err(err) = wine.update_prefix(&config.game.wine.prefix) { this.update(Actions::Toast(Rc::new(( String::from("Failed to create wine prefix"), err.to_string() )))).unwrap(); @@ -519,16 +521,16 @@ impl App { None => this.toast("Failed to get selected wine version", Error::last_os_error()) } } - + LauncherState::VoiceUpdateAvailable(diff) | LauncherState::VoiceNotInstalled(diff) | LauncherState::GameUpdateAvailable(diff) | LauncherState::GameNotInstalled(diff) => { let (sender, receiver) = glib::MainContext::channel::(glib::PRIORITY_DEFAULT); - + let this = this.clone(); let this_copy = this.clone(); - + this.update(Actions::ShowProgressBar).unwrap(); // Download diff