mirror of
https://github.com/an-anime-team/sleepy-launcher.git
synced 2025-02-16 17:59:46 +03:00
Added partial support of wincompatlib
This commit is contained in:
parent
a647e68665
commit
7ac3935ab1
9 changed files with 62 additions and 103 deletions
10
Cargo.lock
generated
10
Cargo.lock
generated
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
|
||||
|
|
|
@ -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::<InstallerUpdate>(glib::PRIORITY_DEFAULT);
|
||||
|
||||
|
||||
let this = this.clone();
|
||||
let this_copy = this.clone();
|
||||
|
||||
|
||||
this.update(Actions::ShowProgressBar).unwrap();
|
||||
|
||||
// Download diff
|
||||
|
|
Loading…
Add table
Reference in a new issue