0.5.0
- improved wine/dxvk features, added command used to run the game
This commit is contained in:
parent
d64d15cf27
commit
ba11109082
5 changed files with 109 additions and 29 deletions
|
@ -1,6 +1,6 @@
|
|||
[package]
|
||||
name = "anime-launcher-sdk"
|
||||
version = "0.4.0"
|
||||
version = "0.5.0"
|
||||
authors = ["Nikita Podvirnyy <suimin.tu.mu.ga.mi@gmail.com>"]
|
||||
license = "GPL-3.0"
|
||||
readme = "README.md"
|
||||
|
|
|
@ -34,6 +34,14 @@ impl Group {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Features {
|
||||
/// Standard environment variables that are applied when you launch the game
|
||||
///
|
||||
/// Available keywords:
|
||||
/// - `%build%` - path to wine build
|
||||
/// - `%prefix%` - path to wine prefix
|
||||
/// - `%temp%` - path to temp folder specified in config file
|
||||
/// - `%launcher%` - path to launcher folder
|
||||
/// - `%game%` - path to the game
|
||||
pub env: HashMap<String, String>
|
||||
}
|
||||
|
||||
|
@ -70,11 +78,12 @@ impl From<&JsonValue> for Features {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Version {
|
||||
pub name: String,
|
||||
pub version: String,
|
||||
pub uri: String
|
||||
pub uri: String,
|
||||
pub features: Option<Features>
|
||||
}
|
||||
|
||||
impl Version {
|
||||
|
|
|
@ -36,6 +36,11 @@ pub fn get_wine_versions(index: &Path) -> anyhow::Result<Vec<wine::Group>> {
|
|||
None => anyhow::bail!("Wrong components index structure: wine group's title not found")
|
||||
};
|
||||
|
||||
let features = match group.get("features") {
|
||||
Some(features) => features.into(),
|
||||
None => wine::Features::default()
|
||||
};
|
||||
|
||||
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();
|
||||
|
@ -43,18 +48,19 @@ pub fn get_wine_versions(index: &Path) -> anyhow::Result<Vec<wine::Group>> {
|
|||
match versions.as_array() {
|
||||
Some(versions) => {
|
||||
for version in versions {
|
||||
wine_versions.push(serde_json::from_value::<wine::Version>(version.to_owned())?);
|
||||
wine_versions.push(wine::Version {
|
||||
name: version["name"].as_str().unwrap().to_string(),
|
||||
title: version["title"].as_str().unwrap().to_string(),
|
||||
uri: version["uri"].as_str().unwrap().to_string(),
|
||||
files: serde_json::from_value::<wine::Files>(version["files"].to_owned())?,
|
||||
features: version.get("features").map(|v| v.into())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -112,7 +118,12 @@ pub fn get_dxvk_versions(index: &Path) -> anyhow::Result<Vec<dxvk::Group>> {
|
|||
match versions.as_array() {
|
||||
Some(versions) => {
|
||||
for version in versions {
|
||||
dxvk_versions.push(serde_json::from_value::<dxvk::Version>(version.to_owned())?);
|
||||
dxvk_versions.push(dxvk::Version {
|
||||
name: version["name"].as_str().unwrap().to_string(),
|
||||
version: version["version"].as_str().unwrap().to_string(),
|
||||
uri: version["uri"].as_str().unwrap().to_string(),
|
||||
features: version.get("features").map(|v| v.into())
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,7 +34,27 @@ impl Group {
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Features {
|
||||
/// Whether this wine group needs DXVK
|
||||
pub need_dxvk: bool,
|
||||
|
||||
/// Command used to launch the game
|
||||
///
|
||||
/// Available keywords:
|
||||
/// - `%build%` - path to wine build
|
||||
/// - `%prefix%` - path to wine prefix
|
||||
/// - `%temp%` - path to temp folder specified in config file
|
||||
/// - `%launcher%` - path to launcher folder
|
||||
/// - `%game%` - path to the game
|
||||
pub command: Option<String>,
|
||||
|
||||
/// Standard environment variables that are applied when you launch the game
|
||||
///
|
||||
/// Available keywords:
|
||||
/// - `%build%` - path to wine build
|
||||
/// - `%prefix%` - path to wine prefix
|
||||
/// - `%temp%` - path to temp folder specified in config file
|
||||
/// - `%launcher%` - path to launcher folder
|
||||
/// - `%game%` - path to the game
|
||||
pub env: HashMap<String, String>
|
||||
}
|
||||
|
||||
|
@ -42,6 +62,7 @@ impl Default for Features {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
need_dxvk: true,
|
||||
command: None,
|
||||
env: HashMap::new()
|
||||
}
|
||||
}
|
||||
|
@ -57,6 +78,11 @@ impl From<&JsonValue> for Features {
|
|||
None => default.need_dxvk
|
||||
},
|
||||
|
||||
command: match value.get("command") {
|
||||
Some(value) => value.as_str().map(|value| value.to_string()),
|
||||
None => default.command
|
||||
},
|
||||
|
||||
env: match value.get("env") {
|
||||
Some(value) => {
|
||||
if let Some(object) = value.as_object() {
|
||||
|
@ -77,21 +103,13 @@ impl From<&JsonValue> for Features {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Version {
|
||||
pub name: String,
|
||||
pub title: String,
|
||||
pub uri: String,
|
||||
pub files: Files
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Files {
|
||||
pub wine: String,
|
||||
pub wine64: Option<String>,
|
||||
pub wineserver: Option<String>,
|
||||
pub wineboot: Option<String>,
|
||||
pub winecfg: Option<String>
|
||||
pub files: Files,
|
||||
pub features: Option<Features>
|
||||
}
|
||||
|
||||
impl Version {
|
||||
|
@ -158,6 +176,15 @@ impl Version {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Files {
|
||||
pub wine: String,
|
||||
pub wine64: Option<String>,
|
||||
pub wineserver: Option<String>,
|
||||
pub wineboot: Option<String>,
|
||||
pub winecfg: Option<String>
|
||||
}
|
||||
|
||||
pub fn get_groups<T: Into<PathBuf>>(components: T) -> anyhow::Result<Vec<Group>> {
|
||||
ComponentsLoader::new(components).get_wine_versions()
|
||||
}
|
||||
|
|
49
src/game.rs
49
src/game.rs
|
@ -1,4 +1,5 @@
|
|||
use std::process::{Command, Stdio};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anime_game_core::genshin::telemetry;
|
||||
|
||||
|
@ -11,6 +12,17 @@ use super::fps_unlocker::FpsUnlocker;
|
|||
#[cfg(feature = "discord-rpc")]
|
||||
use super::discord_rpc::*;
|
||||
|
||||
fn replace_keywords<T: ToString>(command: T, config: &config::Config) -> String {
|
||||
let wine_build = config.game.wine.builds.join(config.game.wine.selected.as_ref().unwrap());
|
||||
|
||||
command.to_string()
|
||||
.replace("%build%", &wine_build.to_string_lossy())
|
||||
.replace("%prefix%", &config.game.wine.prefix.to_string_lossy())
|
||||
.replace("%temp%", &config.launcher.temp.as_ref().unwrap_or(&PathBuf::from("/tmp")).to_string_lossy())
|
||||
.replace("%launcher%", &consts::launcher_dir().unwrap().to_string_lossy())
|
||||
.replace("%game%", &config.game.path.to_string_lossy())
|
||||
}
|
||||
|
||||
/// Try to run the game
|
||||
///
|
||||
/// This function will freeze thread it was called from while the game is running
|
||||
|
@ -28,6 +40,14 @@ pub fn run() -> anyhow::Result<()> {
|
|||
anyhow::bail!("Couldn't find wine executable");
|
||||
};
|
||||
|
||||
let features = match wine.features {
|
||||
Some(features) => features,
|
||||
None => match wine.find_group(&config.components.path)? {
|
||||
Some(group) => group.features,
|
||||
None => anyhow::bail!("Couldn't find wine group")
|
||||
}
|
||||
};
|
||||
|
||||
// Check telemetry servers
|
||||
|
||||
tracing::info!("Checking telemetry");
|
||||
|
@ -86,7 +106,14 @@ pub fn run() -> anyhow::Result<()> {
|
|||
bash_chain += "gamemoderun ";
|
||||
}
|
||||
|
||||
bash_chain += &format!("'{}' ", config.game.wine.builds.join(wine.name).join(wine.files.wine64.unwrap_or(wine.files.wine)).to_string_lossy());
|
||||
let wine_build = config.game.wine.builds.join(&wine.name);
|
||||
|
||||
let run_command = features.command
|
||||
.map(|command| replace_keywords(command, &config))
|
||||
.unwrap_or(format!("'{}'", wine_build.join(wine.files.wine64.unwrap_or(wine.files.wine)).to_string_lossy()));
|
||||
|
||||
bash_chain += &run_command;
|
||||
bash_chain += " ";
|
||||
|
||||
if let Some(virtual_desktop) = config.game.wine.virtual_desktop.get_command() {
|
||||
bash_chain += &format!("{virtual_desktop} ");
|
||||
|
@ -113,7 +140,7 @@ pub fn run() -> anyhow::Result<()> {
|
|||
}
|
||||
|
||||
let bash_chain = match &config.game.command {
|
||||
Some(command) => command.replace("%command%", &bash_chain),
|
||||
Some(command) => replace_keywords(command, &config).replace("%command%", &bash_chain),
|
||||
None => bash_chain
|
||||
};
|
||||
|
||||
|
@ -128,16 +155,22 @@ pub fn run() -> anyhow::Result<()> {
|
|||
command.env("WINEPREFIX", &config.game.wine.prefix);
|
||||
|
||||
// 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);
|
||||
}
|
||||
for (key, value) in features.env.into_iter() {
|
||||
command.env(key, replace_keywords(value, &config));
|
||||
}
|
||||
|
||||
// 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);
|
||||
if let Some(features) = &dxvk.features {
|
||||
for (key, value) in features.env.iter() {
|
||||
command.env(key, replace_keywords(value, &config));
|
||||
}
|
||||
}
|
||||
|
||||
else if let Ok(Some(group)) = dxvk.find_group(&config.components.path) {
|
||||
for (key, value) in group.features.env.into_iter() {
|
||||
command.env(key, replace_keywords(value, &config));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue