Added partial support of wincompatlib

This commit is contained in:
Observer KRypt0n_ 2022-09-25 21:37:30 +02:00
parent a647e68665
commit 7ac3935ab1
9 changed files with 62 additions and 103 deletions

10
Cargo.lock generated
View file

@ -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"

View file

@ -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"

View file

@ -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)
)
}
}

View file

@ -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);
}

View file

@ -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;

View file

@ -1,5 +1,9 @@
use std::path::PathBuf;
use serde::{Serialize, Deserialize};
use wincompatlib::prelude::*;
lazy_static::lazy_static! {
static ref GROUPS: Vec<Group> = vec![
Group {
@ -79,8 +83,19 @@ impl Version {
Ok(List::get()[0].versions[0].clone())
}
pub fn is_downloaded_in<T: ToString>(&self, folder: T) -> bool {
std::path::Path::new(&format!("{}/{}", folder.to_string(), self.name)).exists()
pub fn is_downloaded_in<T: Into<PathBuf>>(&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
)
}
}

View file

@ -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<T: ToString>(path: T) -> Self {
Self { path: path.to_string() }
}
pub fn exists(&self) -> bool {
Self::exists_in(&self.path)
}
pub fn exists_in<T: ToString>(path: T) -> bool {
Path::new(&format!("{}/drive_c", path.to_string())).exists()
}
fn wine<T: ToString>(&self, wine_binary: T, command: &str) -> std::io::Result<Output> {
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<T: ToString>(&self, runners_folder: T, runner: super::wine::Version) -> std::io::Result<Output> {
self.update_with(format!("{}/{}/{}", runners_folder.to_string(), runner.name, runner.files.wine64))
}
pub fn update_with<T: ToString>(&self, wine_binary: T) -> std::io::Result<Output> {
self.wine(wine_binary, "-u")
}
}

View file

@ -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));

View file

@ -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();