feat(star-rail): added multi-edition support
This commit is contained in:
parent
f322763197
commit
d9e1f61ede
5 changed files with 81 additions and 13 deletions
|
@ -11,19 +11,21 @@ crate::config_impl_wine_schema!(launcher_dir);
|
|||
crate::config_impl_dxvk_schema!(launcher_dir);
|
||||
|
||||
pub mod enhancements;
|
||||
pub mod paths;
|
||||
|
||||
pub mod prelude {
|
||||
pub use super::Wine;
|
||||
pub use super::Dxvk;
|
||||
|
||||
pub use super::enhancements::Enhancements;
|
||||
pub use super::paths::Paths;
|
||||
}
|
||||
|
||||
use prelude::*;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Game {
|
||||
pub path: PathBuf,
|
||||
pub path: Paths,
|
||||
pub wine: Wine,
|
||||
pub dxvk: Dxvk,
|
||||
pub enhancements: Enhancements,
|
||||
|
@ -37,7 +39,7 @@ impl Default for Game {
|
|||
let launcher_dir = launcher_dir().expect("Failed to get launcher dir");
|
||||
|
||||
Self {
|
||||
path: launcher_dir.join(concat!("Hon", "kai Sta", "r Rail")),
|
||||
path: Paths::default(),
|
||||
wine: Wine::default(),
|
||||
dxvk: Dxvk::default(),
|
||||
enhancements: Enhancements::default(),
|
||||
|
@ -53,10 +55,7 @@ impl From<&JsonValue> for Game {
|
|||
|
||||
Self {
|
||||
path: match value.get("path") {
|
||||
Some(value) => match value.as_str() {
|
||||
Some(value) => PathBuf::from(value),
|
||||
None => default.path
|
||||
},
|
||||
Some(value) => Paths::from(value),
|
||||
None => default.path
|
||||
},
|
||||
|
||||
|
|
60
src/star_rail/config/schema/game/paths.rs
Normal file
60
src/star_rail/config/schema/game/paths.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use serde::{Serialize, Deserialize};
|
||||
use serde_json::Value as JsonValue;
|
||||
|
||||
use anime_game_core::star_rail::consts::GameEdition;
|
||||
|
||||
use crate::star_rail::consts::launcher_dir;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Paths {
|
||||
pub global: PathBuf,
|
||||
pub china: PathBuf
|
||||
}
|
||||
|
||||
impl Paths {
|
||||
#[inline]
|
||||
/// Get game path for given edition
|
||||
pub fn for_edition(&self, edition: impl Into<GameEdition>) -> &Path {
|
||||
match edition.into() {
|
||||
GameEdition::Global => self.global.as_path(),
|
||||
GameEdition::China => self.china.as_path()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Paths {
|
||||
fn default() -> Self {
|
||||
let launcher_dir = launcher_dir().expect("Failed to get launcher dir");
|
||||
|
||||
Self {
|
||||
global: launcher_dir.join("HSR"),
|
||||
china: launcher_dir.join("HSR China")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<&JsonValue> for Paths {
|
||||
fn from(value: &JsonValue) -> Self {
|
||||
let default = Self::default();
|
||||
|
||||
Self {
|
||||
global: match value.get("global") {
|
||||
Some(value) => match value.as_str() {
|
||||
Some(value) => PathBuf::from(value),
|
||||
None => default.global
|
||||
},
|
||||
None => default.global
|
||||
},
|
||||
|
||||
china: match value.get("china") {
|
||||
Some(value) => match value.as_str() {
|
||||
Some(value) => PathBuf::from(value),
|
||||
None => default.china
|
||||
},
|
||||
None => default.china
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ use serde_json::Value as JsonValue;
|
|||
|
||||
use enum_ordinalize::Ordinalize;
|
||||
|
||||
use anime_game_core::star_rail::consts::GameEdition;
|
||||
|
||||
use crate::config::schema_blanks::prelude::*;
|
||||
use crate::star_rail::consts::launcher_dir;
|
||||
|
||||
|
@ -34,6 +36,7 @@ impl Default for LauncherStyle {
|
|||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Launcher {
|
||||
pub language: String,
|
||||
pub edition: GameEdition,
|
||||
pub style: LauncherStyle,
|
||||
pub temp: Option<PathBuf>,
|
||||
pub repairer: Repairer,
|
||||
|
@ -47,6 +50,7 @@ impl Default for Launcher {
|
|||
fn default() -> Self {
|
||||
Self {
|
||||
language: String::from("en-us"),
|
||||
edition: GameEdition::from_system_lang(),
|
||||
style: LauncherStyle::default(),
|
||||
temp: launcher_dir().ok(),
|
||||
repairer: Repairer::default(),
|
||||
|
@ -67,6 +71,11 @@ impl From<&JsonValue> for Launcher {
|
|||
None => default.language
|
||||
},
|
||||
|
||||
edition: match value.get("edition") {
|
||||
Some(value) => serde_json::from_value(value.clone()).unwrap_or(default.edition),
|
||||
None => default.edition
|
||||
},
|
||||
|
||||
style: match value.get("style") {
|
||||
Some(value) => serde_json::from_value(value.to_owned()).unwrap_or_default(),
|
||||
None => default.style
|
||||
|
|
|
@ -36,8 +36,9 @@ pub fn run() -> anyhow::Result<()> {
|
|||
tracing::info!("Preparing to run the game");
|
||||
|
||||
let config = Config::get()?;
|
||||
let game_path = config.game.path.for_edition(config.launcher.edition).to_path_buf();
|
||||
|
||||
if !config.game.path.exists() {
|
||||
if !game_path.exists() {
|
||||
return Err(anyhow::anyhow!("Game is not installed"));
|
||||
}
|
||||
|
||||
|
@ -45,12 +46,12 @@ pub fn run() -> anyhow::Result<()> {
|
|||
anyhow::bail!("Couldn't find wine executable");
|
||||
};
|
||||
|
||||
let features = wine.features(&config.components.path)?.unwrap_or_default();
|
||||
let features = wine.features(&game_path)?.unwrap_or_default();
|
||||
|
||||
let mut folders = Folders {
|
||||
wine: config.game.wine.builds.join(&wine.name),
|
||||
prefix: config.game.wine.prefix.clone(),
|
||||
game: config.game.path.clone(),
|
||||
game: game_path.clone(),
|
||||
temp: config.launcher.temp.clone().unwrap_or(std::env::temp_dir())
|
||||
};
|
||||
|
||||
|
@ -186,8 +187,7 @@ pub fn run() -> anyhow::Result<()> {
|
|||
|
||||
// We use real current dir here because sandboxed one
|
||||
// obviously doesn't exist
|
||||
command.current_dir(&config.game.path)
|
||||
.spawn()?.wait_with_output()?;
|
||||
command.current_dir(game_path).spawn()?.wait_with_output()?;
|
||||
|
||||
#[cfg(feature = "discord-rpc")]
|
||||
let rpc = if config.launcher.discord_rpc.enabled {
|
||||
|
@ -207,7 +207,7 @@ pub fn run() -> anyhow::Result<()> {
|
|||
let output = Command::new("ps").arg("-A").stdout(Stdio::piped()).output()?;
|
||||
let output = String::from_utf8_lossy(&output.stdout);
|
||||
|
||||
if !output.contains("GenshinImpact.e") && !output.contains("unlocker.exe") {
|
||||
if !output.contains("StarRail.exe") {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,7 +123,7 @@ impl LauncherState {
|
|||
|
||||
Self::get(LauncherStateParams {
|
||||
wine_prefix: config.get_wine_prefix_path(),
|
||||
game_path: config.game.path,
|
||||
game_path: config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
|
||||
patch_servers: config.patch.servers,
|
||||
patch_folder: config.patch.path,
|
||||
|
|
Loading…
Reference in a new issue