0.4.0
- added `Group::find_in`, `Version::find_in` and `Version::find_group` methods to both `wine` and `dxvk` mods - `get_downloaded` now returns list of groups with downloaded versions instead of just a single list - added `features` property to `Group` structs of `wine` and `dxvk` - added support of `[group].features.env` variables to `game::run` - `ComponentsLoader` now caches `get_wine[dxvk]_versions` output - `Config::try_get_selected_wine[dxvk]_info` renamed to `Config::get_selected_wine[dxvk]`
This commit is contained in:
parent
f6daddc4bc
commit
2ff3ad0122
7 changed files with 360 additions and 171 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anime-launcher-sdk"
|
||||
version = "0.3.6"
|
||||
version = "0.4.0"
|
||||
authors = ["Nikita Podvirnyy <suimin.tu.mu.ga.mi@gmail.com>"]
|
||||
license = "GPL-3.0"
|
||||
readme = "README.md"
|
||||
|
@ -12,6 +12,7 @@ anime-game-core = { path = "anime-game-core", features = ["genshin", "all", "sta
|
|||
anyhow = "1.0"
|
||||
dirs = "4.0.0"
|
||||
tracing = "0.1"
|
||||
cached = { version = "0.42", features = ["proc_macro"] }
|
||||
|
||||
serde = { version = "1.0", features = ["derive"], optional = true }
|
||||
serde_json = { version = "1.0", optional = true }
|
||||
|
|
|
@ -1,17 +1,75 @@
|
|||
use std::path::PathBuf;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
use wincompatlib::prelude::*;
|
||||
|
||||
use super::loader::ComponentsLoader;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Group {
|
||||
pub name: String,
|
||||
pub title: String,
|
||||
pub features: Features,
|
||||
pub versions: Vec<Version>
|
||||
}
|
||||
|
||||
impl Group {
|
||||
/// Find dxvk group with given name in components index
|
||||
///
|
||||
/// This method will also check all version names within this group, so both `vanilla` and `dxvk-1.10.3` will work
|
||||
pub fn find_in<T: Into<PathBuf>, F: AsRef<str>>(components: T, name: F) -> anyhow::Result<Option<Self>> {
|
||||
let name = name.as_ref();
|
||||
|
||||
for group in get_groups(components)? {
|
||||
if group.name == name || group.versions.iter().any(move |version| version.name == name) {
|
||||
return Ok(Some(group));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Features {
|
||||
pub env: HashMap<String, String>
|
||||
}
|
||||
|
||||
impl Default for Features {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
env: HashMap::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&JsonValue> for Features {
|
||||
fn from(value: &JsonValue) -> Self {
|
||||
let mut default = Self::default();
|
||||
|
||||
Self {
|
||||
env: match value.get("env") {
|
||||
Some(value) => {
|
||||
if let Some(object) = value.as_object() {
|
||||
for (key, value) in object {
|
||||
if let Some(value) = value.as_str() {
|
||||
default.env.insert(key.to_string(), value.to_string());
|
||||
} else {
|
||||
default.env.insert(key.to_string(), value.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default.env
|
||||
},
|
||||
None => default.env
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Version {
|
||||
pub name: String,
|
||||
|
@ -25,6 +83,32 @@ impl Version {
|
|||
Ok(get_groups(components)?[0].versions[0].clone())
|
||||
}
|
||||
|
||||
/// Find dxvk version with given name in components index
|
||||
pub fn find_in<T: Into<PathBuf>, F: AsRef<str>>(components: T, name: F) -> anyhow::Result<Option<Self>> {
|
||||
let name = name.as_ref();
|
||||
|
||||
for group in get_groups(components)? {
|
||||
if let Some(version) = group.versions.into_iter().find(move |version| version.name == name || version.version == name) {
|
||||
return Ok(Some(version));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Find dxvk group current version belongs to
|
||||
pub fn find_group<T: Into<PathBuf>>(&self, components: T) -> anyhow::Result<Option<Group>> {
|
||||
let name = self.name.as_str();
|
||||
|
||||
for group in get_groups(components)? {
|
||||
if group.versions.iter().any(move |version| version.name == name || version.version == name) {
|
||||
return Ok(Some(group));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Check is current dxvk downloaded in specified folder
|
||||
#[inline]
|
||||
pub fn is_downloaded_in<T: Into<PathBuf>>(&self, folder: T) -> bool {
|
||||
|
@ -62,23 +146,18 @@ pub fn get_groups<T: Into<PathBuf>>(components: T) -> anyhow::Result<Vec<Group>>
|
|||
}
|
||||
|
||||
/// List downloaded dxvk versions in some specific folder
|
||||
pub fn get_downloaded<T: Into<PathBuf>>(components: T, folder: T) -> anyhow::Result<Vec<Version>> {
|
||||
pub fn get_downloaded<T: Into<PathBuf>>(components: T, folder: T) -> anyhow::Result<Vec<Group>> {
|
||||
let mut downloaded = Vec::new();
|
||||
|
||||
let list = get_groups(components)?
|
||||
.into_iter()
|
||||
.flat_map(|group| group.versions)
|
||||
.collect::<Vec<Version>>();
|
||||
let folder: PathBuf = folder.into();
|
||||
|
||||
for entry in folder.into().read_dir()? {
|
||||
let name = entry?.file_name();
|
||||
for mut group in get_groups(components)? {
|
||||
group.versions = group.versions.into_iter()
|
||||
.filter(|version| folder.join(&version.name).exists())
|
||||
.collect();
|
||||
|
||||
for version in &list {
|
||||
if name == version.name.as_str() {
|
||||
downloaded.push(version.clone());
|
||||
|
||||
break;
|
||||
}
|
||||
if !group.versions.is_empty() {
|
||||
downloaded.push(group);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,144 @@ use crate::anime_game_core::traits::git_sync::RemoteGitSync;
|
|||
use super::wine;
|
||||
use super::dxvk;
|
||||
|
||||
/// Try to get wine versions from components index
|
||||
#[tracing::instrument(level = "debug", ret)]
|
||||
#[cached::proc_macro::cached(key = "PathBuf", convert = r##"{ index.to_path_buf() }"##, result)]
|
||||
pub fn get_wine_versions(index: &Path) -> anyhow::Result<Vec<wine::Group>> {
|
||||
tracing::debug!("Getting wine versions");
|
||||
|
||||
let components = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(index.join("components.json"))?)?;
|
||||
|
||||
match components.get("wine") {
|
||||
Some(wine) => match wine.as_array() {
|
||||
Some(groups) => {
|
||||
let mut wine_groups = Vec::with_capacity(groups.len());
|
||||
|
||||
for group in groups {
|
||||
let name = match group.get("name") {
|
||||
Some(name) => match name.as_str() {
|
||||
Some(name) => name.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's name entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's name not found")
|
||||
};
|
||||
|
||||
let title = match group.get("title") {
|
||||
Some(title) => match title.as_str() {
|
||||
Some(title) => title.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's title entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's title not found")
|
||||
};
|
||||
|
||||
let versions = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(index.join("wine").join(format!("{name}.json")))?)?;
|
||||
|
||||
let mut wine_versions = Vec::new();
|
||||
|
||||
match versions.as_array() {
|
||||
Some(versions) => {
|
||||
for version in versions {
|
||||
wine_versions.push(serde_json::from_value::<wine::Version>(version.to_owned())?);
|
||||
}
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine versions must be a list")
|
||||
}
|
||||
|
||||
let features = match group.get("features") {
|
||||
Some(features) => features.into(),
|
||||
None => wine::Features::default()
|
||||
};
|
||||
|
||||
wine_groups.push(wine::Group {
|
||||
name,
|
||||
title,
|
||||
features,
|
||||
versions: wine_versions
|
||||
});
|
||||
}
|
||||
|
||||
Ok(wine_groups)
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry must be a list")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry not found")
|
||||
}
|
||||
}
|
||||
|
||||
/// Try to get dxvk versions from components index
|
||||
#[tracing::instrument(level = "debug", ret)]
|
||||
#[cached::proc_macro::cached(key = "PathBuf", convert = r##"{ index.to_path_buf() }"##, result)]
|
||||
pub fn get_dxvk_versions(index: &Path) -> anyhow::Result<Vec<dxvk::Group>> {
|
||||
tracing::debug!("Getting dxvk versions");
|
||||
|
||||
let components = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(index.join("components.json"))?)?;
|
||||
|
||||
match components.get("dxvk") {
|
||||
Some(dxvk) => match dxvk.as_array() {
|
||||
Some(groups) => {
|
||||
let mut dxvk_groups = Vec::with_capacity(groups.len());
|
||||
|
||||
for group in groups {
|
||||
let name = match group.get("name") {
|
||||
Some(name) => match name.as_str() {
|
||||
Some(name) => name.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's name entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's name not found")
|
||||
};
|
||||
|
||||
let title = match group.get("title") {
|
||||
Some(title) => match title.as_str() {
|
||||
Some(title) => title.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's title entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's title not found")
|
||||
};
|
||||
|
||||
let versions = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(index.join("dxvk").join(format!("{name}.json")))?)?;
|
||||
|
||||
let mut dxvk_versions = Vec::new();
|
||||
|
||||
match versions.as_array() {
|
||||
Some(versions) => {
|
||||
for version in versions {
|
||||
dxvk_versions.push(serde_json::from_value::<dxvk::Version>(version.to_owned())?);
|
||||
}
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine versions must be a list")
|
||||
}
|
||||
|
||||
let features = match group.get("features") {
|
||||
Some(features) => features.into(),
|
||||
None => dxvk::Features::default()
|
||||
};
|
||||
|
||||
dxvk_groups.push(dxvk::Group {
|
||||
name,
|
||||
title,
|
||||
features,
|
||||
versions: dxvk_versions
|
||||
});
|
||||
}
|
||||
|
||||
Ok(dxvk_groups)
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry must be a list")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry not found")
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct ComponentsLoader {
|
||||
folder: PathBuf
|
||||
|
@ -22,127 +160,13 @@ impl ComponentsLoader {
|
|||
}
|
||||
}
|
||||
|
||||
/// Try to get wine versions from components index
|
||||
#[tracing::instrument(level = "debug", ret)]
|
||||
pub fn get_wine_versions(&self) -> anyhow::Result<Vec<wine::Group>> {
|
||||
tracing::debug!("Getting wine versions");
|
||||
|
||||
let components = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(self.folder.join("components.json"))?)?;
|
||||
|
||||
match components.get("wine") {
|
||||
Some(wine) => match wine.as_array() {
|
||||
Some(groups) => {
|
||||
let mut wine_groups = Vec::with_capacity(groups.len());
|
||||
|
||||
for group in groups {
|
||||
let name = match group.get("name") {
|
||||
Some(name) => match name.as_str() {
|
||||
Some(name) => name.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's name entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's name not found")
|
||||
};
|
||||
|
||||
let title = match group.get("title") {
|
||||
Some(title) => match title.as_str() {
|
||||
Some(title) => title.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's title entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine group's title not found")
|
||||
};
|
||||
|
||||
let versions = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(self.folder.join("wine").join(format!("{name}.json")))?)?;
|
||||
|
||||
let mut wine_versions = Vec::new();
|
||||
|
||||
match versions.as_array() {
|
||||
Some(versions) => {
|
||||
for version in versions {
|
||||
wine_versions.push(serde_json::from_value::<wine::Version>(version.to_owned())?);
|
||||
}
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine versions must be a list")
|
||||
}
|
||||
|
||||
wine_groups.push(wine::Group {
|
||||
name,
|
||||
title,
|
||||
versions: wine_versions
|
||||
});
|
||||
}
|
||||
|
||||
Ok(wine_groups)
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry must be a list")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry not found")
|
||||
}
|
||||
get_wine_versions(&self.folder)
|
||||
}
|
||||
|
||||
/// Try to get dxvk versions from components index
|
||||
#[tracing::instrument(level = "debug", ret)]
|
||||
pub fn get_dxvk_versions(&self) -> anyhow::Result<Vec<dxvk::Group>> {
|
||||
tracing::debug!("Getting dxvk versions");
|
||||
|
||||
let components = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(self.folder.join("components.json"))?)?;
|
||||
|
||||
match components.get("dxvk") {
|
||||
Some(dxvk) => match dxvk.as_array() {
|
||||
Some(groups) => {
|
||||
let mut dxvk_groups = Vec::with_capacity(groups.len());
|
||||
|
||||
for group in groups {
|
||||
let name = match group.get("name") {
|
||||
Some(name) => match name.as_str() {
|
||||
Some(name) => name.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's name entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's name not found")
|
||||
};
|
||||
|
||||
let title = match group.get("title") {
|
||||
Some(title) => match title.as_str() {
|
||||
Some(title) => title.to_string(),
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's title entry must be a string")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: dxvk group's title not found")
|
||||
};
|
||||
|
||||
let versions = serde_json::from_str::<serde_json::Value>(&std::fs::read_to_string(self.folder.join("dxvk").join(format!("{name}.json")))?)?;
|
||||
|
||||
let mut dxvk_versions = Vec::new();
|
||||
|
||||
match versions.as_array() {
|
||||
Some(versions) => {
|
||||
for version in versions {
|
||||
dxvk_versions.push(serde_json::from_value::<dxvk::Version>(version.to_owned())?);
|
||||
}
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine versions must be a list")
|
||||
}
|
||||
|
||||
dxvk_groups.push(dxvk::Group {
|
||||
name,
|
||||
title,
|
||||
versions: dxvk_versions
|
||||
});
|
||||
}
|
||||
|
||||
Ok(dxvk_groups)
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry must be a list")
|
||||
}
|
||||
|
||||
None => anyhow::bail!("Wrong components index structure: wine entry not found")
|
||||
}
|
||||
get_dxvk_versions(&self.folder)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,82 @@
|
|||
use std::path::PathBuf;
|
||||
use std::collections::HashMap;
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
use wincompatlib::prelude::*;
|
||||
|
||||
use super::loader::ComponentsLoader;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Group {
|
||||
pub name: String,
|
||||
pub title: String,
|
||||
pub features: Features,
|
||||
pub versions: Vec<Version>
|
||||
}
|
||||
|
||||
impl Group {
|
||||
/// Find wine group with given name in components index
|
||||
///
|
||||
/// This method will also check all version names within this group, so both `wine-ge-proton` and `lutris-GE-Proton7-37-x86_64` will work
|
||||
pub fn find_in<T: Into<PathBuf>, F: AsRef<str>>(components: T, name: F) -> anyhow::Result<Option<Self>> {
|
||||
let name = name.as_ref();
|
||||
|
||||
for group in get_groups(components)? {
|
||||
if group.name == name || group.versions.iter().any(move |version| version.name == name) {
|
||||
return Ok(Some(group));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Features {
|
||||
pub need_dxvk: bool,
|
||||
pub env: HashMap<String, String>
|
||||
}
|
||||
|
||||
impl Default for Features {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
need_dxvk: true,
|
||||
env: HashMap::new()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&JsonValue> for Features {
|
||||
fn from(value: &JsonValue) -> Self {
|
||||
let mut default = Self::default();
|
||||
|
||||
Self {
|
||||
need_dxvk: match value.get("need_dxvk") {
|
||||
Some(value) => value.as_bool().unwrap_or(default.need_dxvk),
|
||||
None => default.need_dxvk
|
||||
},
|
||||
|
||||
env: match value.get("env") {
|
||||
Some(value) => {
|
||||
if let Some(object) = value.as_object() {
|
||||
for (key, value) in object {
|
||||
if let Some(value) = value.as_str() {
|
||||
default.env.insert(key.to_string(), value.to_string());
|
||||
} else {
|
||||
default.env.insert(key.to_string(), value.to_string());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default.env
|
||||
},
|
||||
None => default.env
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Version {
|
||||
pub name: String,
|
||||
|
@ -35,6 +100,32 @@ impl Version {
|
|||
Ok(get_groups(components)?[0].versions[0].clone())
|
||||
}
|
||||
|
||||
/// Find wine version with given name in components index
|
||||
pub fn find_in<T: Into<PathBuf>, F: AsRef<str>>(components: T, name: F) -> anyhow::Result<Option<Self>> {
|
||||
let name = name.as_ref();
|
||||
|
||||
for group in get_groups(components)? {
|
||||
if let Some(version) = group.versions.into_iter().find(move |version| version.name == name) {
|
||||
return Ok(Some(version));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Find wine group current version belongs to
|
||||
pub fn find_group<T: Into<PathBuf>>(&self, components: T) -> anyhow::Result<Option<Group>> {
|
||||
let name = self.name.as_str();
|
||||
|
||||
for group in get_groups(components)? {
|
||||
if group.versions.iter().any(move |version| version.name == name) {
|
||||
return Ok(Some(group));
|
||||
}
|
||||
}
|
||||
|
||||
Ok(None)
|
||||
}
|
||||
|
||||
/// Check is current wine downloaded in specified folder
|
||||
#[inline]
|
||||
pub fn is_downloaded_in<T: Into<PathBuf>>(&self, folder: T) -> bool {
|
||||
|
@ -72,27 +163,20 @@ pub fn get_groups<T: Into<PathBuf>>(components: T) -> anyhow::Result<Vec<Group>>
|
|||
}
|
||||
|
||||
/// List downloaded wine versions in some specific folder
|
||||
pub fn get_downloaded<T: Into<PathBuf>>(components: T, folder: T) -> anyhow::Result<Vec<Version>> {
|
||||
pub fn get_downloaded<T: Into<PathBuf>>(components: T, folder: T) -> anyhow::Result<Vec<Group>> {
|
||||
let mut downloaded = Vec::new();
|
||||
|
||||
let list = get_groups(components)?
|
||||
.into_iter()
|
||||
.flat_map(|group| group.versions)
|
||||
.collect::<Vec<Version>>();
|
||||
let folder: PathBuf = folder.into();
|
||||
|
||||
for entry in folder.into().read_dir()? {
|
||||
let name = entry?.file_name();
|
||||
for mut group in get_groups(components)? {
|
||||
group.versions = group.versions.into_iter()
|
||||
.filter(|version| folder.join(&version.name).exists())
|
||||
.collect();
|
||||
|
||||
for version in &list {
|
||||
if name == version.name.as_str() {
|
||||
downloaded.push(version.clone());
|
||||
|
||||
break;
|
||||
}
|
||||
if !group.versions.is_empty() {
|
||||
downloaded.push(group);
|
||||
}
|
||||
}
|
||||
|
||||
downloaded.sort_by(|a, b| b.name.partial_cmp(&a.name).unwrap());
|
||||
|
||||
Ok(downloaded)
|
||||
}
|
||||
|
|
|
@ -190,22 +190,22 @@ impl From<&JsonValue> for Config {
|
|||
}
|
||||
|
||||
#[cfg(feature = "components")]
|
||||
use crate::components::wine::{self, Version as WineVersion};
|
||||
use crate::components::wine;
|
||||
|
||||
#[cfg(feature = "components")]
|
||||
use crate::components::dxvk::{self, Version as DxvkVersion};
|
||||
use crate::components::dxvk;
|
||||
|
||||
#[cfg(feature = "components")]
|
||||
impl Config {
|
||||
pub fn try_get_selected_wine_info(&self) -> anyhow::Result<Option<WineVersion>> {
|
||||
/// Try to get selected wine version
|
||||
///
|
||||
/// Returns:
|
||||
/// 1) `Ok(Some(..))` if version selected and found
|
||||
/// 2) `Ok(None)` if version wasn't found, so likely too old or just incorrect
|
||||
/// 3) `Err(..)` if failed to get selected wine version
|
||||
pub fn get_selected_wine(&self) -> anyhow::Result<Option<wine::Version>> {
|
||||
match &self.game.wine.selected {
|
||||
Some(selected) => {
|
||||
Ok(wine::get_groups(&self.components.path)?
|
||||
.iter()
|
||||
.flat_map(|group| group.versions.clone())
|
||||
.find(|version| version.name.eq(selected)))
|
||||
}
|
||||
|
||||
Some(selected) => wine::Version::find_in(&self.components.path, selected),
|
||||
None => Ok(None)
|
||||
}
|
||||
}
|
||||
|
@ -216,15 +216,9 @@ impl Config {
|
|||
/// 1) `Ok(Some(..))` if version was found
|
||||
/// 2) `Ok(None)` if version wasn't found, so too old or dxvk is not applied
|
||||
/// 3) `Err(..)` if failed to get applied dxvk version, likely because wrong prefix path specified
|
||||
pub fn try_get_selected_dxvk_info(&self) -> anyhow::Result<Option<DxvkVersion>> {
|
||||
pub fn get_selected_dxvk(&self) -> anyhow::Result<Option<dxvk::Version>> {
|
||||
match wincompatlib::dxvk::Dxvk::get_version(&self.game.wine.prefix)? {
|
||||
Some(version) => {
|
||||
Ok(dxvk::get_groups(&self.components.path)?
|
||||
.iter()
|
||||
.flat_map(|group| group.versions.clone())
|
||||
.find(move |dxvk| dxvk.version == version))
|
||||
}
|
||||
|
||||
Some(version) => dxvk::Version::find_in(&self.components.path, version),
|
||||
None => Ok(None)
|
||||
}
|
||||
}
|
||||
|
|
17
src/game.rs
17
src/game.rs
|
@ -24,7 +24,7 @@ pub fn run() -> anyhow::Result<()> {
|
|||
return Err(anyhow::anyhow!("Game is not installed"));
|
||||
}
|
||||
|
||||
let Some(wine) = config.try_get_selected_wine_info()? else {
|
||||
let Some(wine) = config.get_selected_wine()? else {
|
||||
anyhow::bail!("Couldn't find wine executable");
|
||||
};
|
||||
|
||||
|
@ -127,10 +127,17 @@ pub fn run() -> anyhow::Result<()> {
|
|||
command.env("WINEARCH", "win64");
|
||||
command.env("WINEPREFIX", &config.game.wine.prefix);
|
||||
|
||||
// Add DXVK_ASYNC=1 for dxvk-async builds automatically
|
||||
if let Ok(Some(dxvk)) = &config.try_get_selected_dxvk_info() {
|
||||
if dxvk.version.contains("async") {
|
||||
command.env("DXVK_ASYNC", "1");
|
||||
// Add environment flags for selected wine
|
||||
if let Ok(Some(wine )) = config.get_selected_wine() {
|
||||
if let Ok(Some(group)) = wine.find_group(&config.components.path) {
|
||||
command.envs(group.features.env);
|
||||
}
|
||||
}
|
||||
|
||||
// Add environment flags for selected dxvk
|
||||
if let Ok(Some(dxvk )) = config.get_selected_dxvk() {
|
||||
if let Ok(Some(group)) = dxvk.find_group(&config.components.path) {
|
||||
command.envs(group.features.env);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,7 +148,7 @@ impl LauncherState {
|
|||
// Check wine existence
|
||||
#[cfg(feature = "components")]
|
||||
{
|
||||
if config.try_get_selected_wine_info()?.is_none() {
|
||||
if config.get_selected_wine()?.is_none() {
|
||||
return Ok(Self::WineNotInstalled);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue