feat: several changes
- Reworked config properties parsing; - Improved multi-region support; - Removed legacy compatibility code (genshin game paths)
This commit is contained in:
parent
d72eb796cf
commit
8572d551f8
21 changed files with 327 additions and 302 deletions
|
@ -22,13 +22,10 @@ macro_rules! config_impl_dxvk_schema {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
builds: match value.get("builds") {
|
builds: value.get("builds")
|
||||||
Some(value) => match value.as_str() {
|
.and_then(|value| value.as_str())
|
||||||
Some(value) => PathBuf::from(value),
|
.map(PathBuf::from)
|
||||||
None => default.builds
|
.unwrap_or(default.builds),
|
||||||
},
|
|
||||||
None => default.builds
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,15 +12,13 @@ impl From<&JsonValue> for Framerate {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
focused: match value.get("focused") {
|
focused: value.get("focused")
|
||||||
Some(value) => value.as_u64().unwrap_or(default.focused),
|
.and_then(JsonValue::as_u64)
|
||||||
None => default.focused
|
.unwrap_or(default.focused),
|
||||||
},
|
|
||||||
|
|
||||||
unfocused: match value.get("unfocused") {
|
unfocused: value.get("unfocused")
|
||||||
Some(value) => value.as_u64().unwrap_or(default.unfocused),
|
.and_then(JsonValue::as_u64)
|
||||||
None => default.unfocused
|
.unwrap_or(default.unfocused)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,45 +49,37 @@ impl From<&JsonValue> for Gamescope {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
enabled: match value.get("enabled") {
|
enabled: value.get("enabled")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.enabled),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.enabled
|
.unwrap_or(default.enabled),
|
||||||
},
|
|
||||||
|
|
||||||
game: match value.get("game") {
|
game: value.get("game")
|
||||||
Some(value) => Size::from(value),
|
.map(Size::from)
|
||||||
None => default.game
|
.unwrap_or(default.game),
|
||||||
},
|
|
||||||
|
|
||||||
gamescope: match value.get("gamescope") {
|
gamescope: value.get("gamescope")
|
||||||
Some(value) => Size::from(value),
|
.map(Size::from)
|
||||||
None => default.gamescope
|
.unwrap_or(default.gamescope),
|
||||||
},
|
|
||||||
|
|
||||||
framerate: match value.get("framerate") {
|
framerate: value.get("framerate")
|
||||||
Some(value) => Framerate::from(value),
|
.map(Framerate::from)
|
||||||
None => default.framerate
|
.unwrap_or(default.framerate),
|
||||||
},
|
|
||||||
|
|
||||||
integer_scaling: match value.get("integer_scaling") {
|
integer_scaling: value.get("integer_scaling")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.integer_scaling),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.integer_scaling
|
.unwrap_or(default.integer_scaling),
|
||||||
},
|
|
||||||
|
|
||||||
fsr: match value.get("fsr") {
|
fsr: value.get("fsr")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.fsr),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.fsr
|
.unwrap_or(default.fsr),
|
||||||
},
|
|
||||||
|
|
||||||
nis: match value.get("nis") {
|
nis: value.get("nis")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.nis),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.nis
|
.unwrap_or(default.nis),
|
||||||
},
|
|
||||||
|
|
||||||
window_type: match value.get("window_type") {
|
window_type: value.get("window_type")
|
||||||
Some(value) => WindowType::from(value),
|
.map(WindowType::from)
|
||||||
None => default.window_type
|
.unwrap_or(default.window_type)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -99,6 +91,7 @@ fn is_legacy_version() -> bool {
|
||||||
Command::new("gamescope").arg("--help").output()
|
Command::new("gamescope").arg("--help").output()
|
||||||
|
|
||||||
// if no --filter, then it's legacy version
|
// if no --filter, then it's legacy version
|
||||||
|
// also for whatever reason --help is printed to stderr
|
||||||
.map(|help| !String::from_utf8_lossy(&help.stderr).contains("-F, --filter"))
|
.map(|help| !String::from_utf8_lossy(&help.stderr).contains("-F, --filter"))
|
||||||
|
|
||||||
// If failed to launch gamescope, then yes, it's legacy (it's not but meh)
|
// If failed to launch gamescope, then yes, it's legacy (it's not but meh)
|
||||||
|
|
|
@ -12,15 +12,13 @@ impl From<&JsonValue> for Size {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
width: match value.get("width") {
|
width: value.get("width")
|
||||||
Some(value) => value.as_u64().unwrap_or(default.width),
|
.and_then(JsonValue::as_u64)
|
||||||
None => default.width
|
.unwrap_or(default.width),
|
||||||
},
|
|
||||||
|
|
||||||
height: match value.get("height") {
|
height: value.get("height")
|
||||||
Some(value) => value.as_u64().unwrap_or(default.height),
|
.and_then(JsonValue::as_u64)
|
||||||
None => default.height
|
.unwrap_or(default.height)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,15 +22,13 @@ impl From<&JsonValue> for Repairer {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
threads: match value.get("threads") {
|
threads: value.get("threads")
|
||||||
Some(value) => value.as_u64().unwrap_or(default.threads),
|
.and_then(JsonValue::as_u64)
|
||||||
None => default.threads
|
.unwrap_or(default.threads),
|
||||||
},
|
|
||||||
|
|
||||||
fast: match value.get("fast") {
|
fast: value.get("fast")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.fast),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.fast
|
.unwrap_or(default.fast)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,15 +47,13 @@ impl From<&JsonValue> for Sandbox {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
enabled: match value.get("enabled") {
|
enabled: value.get("enabled")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.enabled),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.enabled
|
.unwrap_or(default.enabled),
|
||||||
},
|
|
||||||
|
|
||||||
isolate_home: match value.get("isolate_home") {
|
isolate_home: value.get("isolate_home")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.isolate_home),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.isolate_home
|
.unwrap_or(default.isolate_home),
|
||||||
},
|
|
||||||
|
|
||||||
hostname: match value.get("hostname") {
|
hostname: match value.get("hostname") {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
|
@ -88,25 +86,19 @@ impl From<&JsonValue> for Sandbox {
|
||||||
private: match value.get("private") {
|
private: match value.get("private") {
|
||||||
Some(value) => match value.as_array() {
|
Some(value) => match value.as_array() {
|
||||||
Some(values) => {
|
Some(values) => {
|
||||||
let mut private = Vec::new();
|
values.iter()
|
||||||
|
.flat_map(|value| value.as_str())
|
||||||
for value in values {
|
.map(|value| value.to_string())
|
||||||
if let Some(server) = value.as_str() {
|
.collect()
|
||||||
private.push(server.to_string());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private
|
|
||||||
},
|
},
|
||||||
None => default.private
|
None => default.private
|
||||||
},
|
},
|
||||||
None => default.private
|
None => default.private
|
||||||
},
|
},
|
||||||
|
|
||||||
mounts: match value.get("mounts") {
|
mounts: value.get("mounts")
|
||||||
Some(value) => Mounts::from(value),
|
.map(Mounts::from)
|
||||||
None => default.mounts
|
.unwrap_or(default.mounts)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,21 +48,15 @@ macro_rules! config_impl_wine_schema {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
prefix: match value.get("prefix") {
|
prefix: value.get("prefix")
|
||||||
Some(value) => match value.as_str() {
|
.and_then(|value| value.as_str())
|
||||||
Some(value) => PathBuf::from(value),
|
.map(PathBuf::from)
|
||||||
None => default.prefix
|
.unwrap_or(default.prefix),
|
||||||
},
|
|
||||||
None => default.prefix
|
|
||||||
},
|
|
||||||
|
|
||||||
builds: match value.get("builds") {
|
builds: value.get("builds")
|
||||||
Some(value) => match value.as_str() {
|
.and_then(|value| value.as_str())
|
||||||
Some(value) => PathBuf::from(value),
|
.map(PathBuf::from)
|
||||||
None => default.builds
|
.unwrap_or(default.builds),
|
||||||
},
|
|
||||||
None => default.builds
|
|
||||||
},
|
|
||||||
|
|
||||||
selected: match value.get("selected") {
|
selected: match value.get("selected") {
|
||||||
Some(value) => {
|
Some(value) => {
|
||||||
|
@ -78,30 +72,25 @@ macro_rules! config_impl_wine_schema {
|
||||||
None => default.selected
|
None => default.selected
|
||||||
},
|
},
|
||||||
|
|
||||||
sync: match value.get("sync") {
|
sync: value.get("sync")
|
||||||
Some(value) => WineSync::from(value),
|
.map(WineSync::from)
|
||||||
None => default.sync
|
.unwrap_or(default.sync),
|
||||||
},
|
|
||||||
|
|
||||||
language: match value.get("language") {
|
language: value.get("language")
|
||||||
Some(value) => WineLang::from(value),
|
.map(WineLang::from)
|
||||||
None => default.language
|
.unwrap_or(default.language),
|
||||||
},
|
|
||||||
|
|
||||||
borderless: match value.get("borderless") {
|
borderless: value.get("borderless")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.borderless),
|
.and_then(|value| value.as_bool())
|
||||||
None => default.borderless
|
.unwrap_or(default.borderless),
|
||||||
},
|
|
||||||
|
|
||||||
virtual_desktop: match value.get("virtual_desktop") {
|
virtual_desktop: value.get("virtual_desktop")
|
||||||
Some(value) => VirtualDesktop::from(value),
|
.map(VirtualDesktop::from)
|
||||||
None => default.virtual_desktop
|
.unwrap_or(default.virtual_desktop),
|
||||||
},
|
|
||||||
|
|
||||||
shared_libraries: match value.get("shared_libraries") {
|
shared_libraries: value.get("shared_libraries")
|
||||||
Some(value) => SharedLibraries::from(value),
|
.map(SharedLibraries::from)
|
||||||
None => default.shared_libraries
|
.unwrap_or(default.shared_libraries),
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,20 +26,17 @@ impl From<&JsonValue> for VirtualDesktop {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
enabled: match value.get("enabled") {
|
enabled: value.get("enabled")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.enabled),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.enabled
|
.unwrap_or(default.enabled),
|
||||||
},
|
|
||||||
|
|
||||||
width: match value.get("width") {
|
width: value.get("width")
|
||||||
Some(value) => value.as_u64().unwrap_or(default.width),
|
.and_then(JsonValue::as_u64)
|
||||||
None => default.width
|
.unwrap_or(default.width),
|
||||||
},
|
|
||||||
|
|
||||||
height: match value.get("height") {
|
height: value.get("height")
|
||||||
Some(value) => value.as_u64().unwrap_or(default.height),
|
.and_then(JsonValue::as_u64)
|
||||||
None => default.height
|
.unwrap_or(default.height)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,31 +23,26 @@ impl From<&JsonValue> for Enhancements {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fsr: match value.get("fsr") {
|
fsr: value.get("fsr")
|
||||||
Some(value) => Fsr::from(value),
|
.map(Fsr::from)
|
||||||
None => default.fsr
|
.unwrap_or(default.fsr),
|
||||||
},
|
|
||||||
|
|
||||||
gamemode: match value.get("gamemode") {
|
gamemode: value.get("gamemode")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.gamemode),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.gamemode
|
.unwrap_or(default.gamemode),
|
||||||
},
|
|
||||||
|
|
||||||
hud: match value.get("hud") {
|
hud: value.get("hud")
|
||||||
Some(value) => HUD::from(value),
|
.map(HUD::from)
|
||||||
None => default.hud
|
.unwrap_or(default.hud),
|
||||||
},
|
|
||||||
|
|
||||||
#[cfg(feature = "fps-unlocker")]
|
#[cfg(feature = "fps-unlocker")]
|
||||||
fps_unlocker: match value.get("fps_unlocker") {
|
fps_unlocker: value.get("fps_unlocker")
|
||||||
Some(value) => FpsUnlocker::from(value),
|
.map(FpsUnlocker::from)
|
||||||
None => default.fps_unlocker
|
.unwrap_or(default.fps_unlocker),
|
||||||
},
|
|
||||||
|
|
||||||
gamescope: match value.get("gamescope") {
|
gamescope: value.get("gamescope")
|
||||||
Some(value) => Gamescope::from(value),
|
.map(Gamescope::from)
|
||||||
None => default.gamescope
|
.unwrap_or(default.gamescope)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,10 +65,9 @@ impl From<&JsonValue> for Game {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
path: match value.get("path") {
|
path: value.get("path")
|
||||||
Some(value) => Paths::from(value),
|
.map(Paths::from)
|
||||||
None => default.path
|
.unwrap_or(default.path),
|
||||||
},
|
|
||||||
|
|
||||||
voices: match value.get("voices") {
|
voices: match value.get("voices") {
|
||||||
Some(value) => match value.as_array() {
|
Some(value) => match value.as_array() {
|
||||||
|
@ -88,20 +87,17 @@ impl From<&JsonValue> for Game {
|
||||||
None => default.voices
|
None => default.voices
|
||||||
},
|
},
|
||||||
|
|
||||||
wine: match value.get("wine") {
|
wine: value.get("wine")
|
||||||
Some(value) => Wine::from(value),
|
.map(Wine::from)
|
||||||
None => default.wine
|
.unwrap_or(default.wine),
|
||||||
},
|
|
||||||
|
|
||||||
dxvk: match value.get("dxvk") {
|
dxvk: value.get("dxvk")
|
||||||
Some(value) => Dxvk::from(value),
|
.map(Dxvk::from)
|
||||||
None => default.dxvk
|
.unwrap_or(default.dxvk),
|
||||||
},
|
|
||||||
|
|
||||||
enhancements: match value.get("enhancements") {
|
enhancements: value.get("enhancements")
|
||||||
Some(value) => Enhancements::from(value),
|
.map(Enhancements::from)
|
||||||
None => default.enhancements
|
.unwrap_or(default.enhancements),
|
||||||
},
|
|
||||||
|
|
||||||
environment: match value.get("environment") {
|
environment: match value.get("environment") {
|
||||||
Some(value) => match value.as_object() {
|
Some(value) => match value.as_object() {
|
||||||
|
|
|
@ -39,38 +39,16 @@ impl From<&JsonValue> for Paths {
|
||||||
fn from(value: &JsonValue) -> Self {
|
fn from(value: &JsonValue) -> Self {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
// SDK 0.5.11 (launcher 3.3.0) and earlier
|
Self {
|
||||||
if value.is_string() {
|
global: value.get("global")
|
||||||
let path = PathBuf::from(value.as_str().unwrap());
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or(default.global),
|
||||||
|
|
||||||
Self {
|
china: value.get("china")
|
||||||
china: match path.parent() {
|
.and_then(JsonValue::as_str)
|
||||||
Some(parent) => parent.join(concat!("Yu", "anS", "hen")),
|
.map(PathBuf::from)
|
||||||
None => default.china
|
.unwrap_or(default.china),
|
||||||
},
|
|
||||||
global: path
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// SDK 0.5.12 and later
|
|
||||||
else {
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,25 +16,21 @@ impl From<&JsonValue> for Enhancements {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fsr: match value.get("fsr") {
|
fsr: value.get("fsr")
|
||||||
Some(value) => Fsr::from(value),
|
.map(Fsr::from)
|
||||||
None => default.fsr
|
.unwrap_or(default.fsr),
|
||||||
},
|
|
||||||
|
|
||||||
gamemode: match value.get("gamemode") {
|
gamemode: value.get("gamemode")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.gamemode),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.gamemode
|
.unwrap_or(default.gamemode),
|
||||||
},
|
|
||||||
|
|
||||||
hud: match value.get("hud") {
|
hud: value.get("hud")
|
||||||
Some(value) => HUD::from(value),
|
.map(HUD::from)
|
||||||
None => default.hud
|
.unwrap_or(default.hud),
|
||||||
},
|
|
||||||
|
|
||||||
gamescope: match value.get("gamescope") {
|
gamescope: value.get("gamescope")
|
||||||
Some(value) => Gamescope::from(value),
|
.map(Gamescope::from)
|
||||||
None => default.gamescope
|
.unwrap_or(default.gamescope)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,13 @@ use crate::honkai::consts::launcher_dir;
|
||||||
crate::config_impl_wine_schema!(launcher_dir);
|
crate::config_impl_wine_schema!(launcher_dir);
|
||||||
crate::config_impl_dxvk_schema!(launcher_dir);
|
crate::config_impl_dxvk_schema!(launcher_dir);
|
||||||
|
|
||||||
|
pub mod paths;
|
||||||
pub mod enhancements;
|
pub mod enhancements;
|
||||||
|
|
||||||
pub mod prelude {
|
pub mod prelude {
|
||||||
pub use super::Wine;
|
pub use super::Wine;
|
||||||
pub use super::Dxvk;
|
pub use super::Dxvk;
|
||||||
|
pub use super::paths::Paths;
|
||||||
pub use super::enhancements::Enhancements;
|
pub use super::enhancements::Enhancements;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +24,7 @@ use prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct Game {
|
pub struct Game {
|
||||||
pub path: PathBuf,
|
pub path: Paths,
|
||||||
pub wine: Wine,
|
pub wine: Wine,
|
||||||
pub dxvk: Dxvk,
|
pub dxvk: Dxvk,
|
||||||
pub enhancements: Enhancements,
|
pub enhancements: Enhancements,
|
||||||
|
@ -33,10 +35,8 @@ pub struct Game {
|
||||||
impl Default for Game {
|
impl Default for Game {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
let launcher_dir = launcher_dir().expect("Failed to get launcher dir");
|
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
path: launcher_dir.join(concat!("Hon", "kai Imp", "act")),
|
path: Paths::default(),
|
||||||
wine: Wine::default(),
|
wine: Wine::default(),
|
||||||
dxvk: Dxvk::default(),
|
dxvk: Dxvk::default(),
|
||||||
enhancements: Enhancements::default(),
|
enhancements: Enhancements::default(),
|
||||||
|
@ -51,28 +51,21 @@ impl From<&JsonValue> for Game {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
path: match value.get("path") {
|
path: value.get("path")
|
||||||
Some(value) => match value.as_str() {
|
.map(Paths::from)
|
||||||
Some(value) => PathBuf::from(value),
|
.unwrap_or(default.path),
|
||||||
None => default.path
|
|
||||||
},
|
|
||||||
None => default.path
|
|
||||||
},
|
|
||||||
|
|
||||||
wine: match value.get("wine") {
|
wine: value.get("wine")
|
||||||
Some(value) => Wine::from(value),
|
.map(Wine::from)
|
||||||
None => default.wine
|
.unwrap_or(default.wine),
|
||||||
},
|
|
||||||
|
|
||||||
dxvk: match value.get("dxvk") {
|
dxvk: value.get("dxvk")
|
||||||
Some(value) => Dxvk::from(value),
|
.map(Dxvk::from)
|
||||||
None => default.dxvk
|
.unwrap_or(default.dxvk),
|
||||||
},
|
|
||||||
|
|
||||||
enhancements: match value.get("enhancements") {
|
enhancements: value.get("enhancements")
|
||||||
Some(value) => Enhancements::from(value),
|
.map(Enhancements::from)
|
||||||
None => default.enhancements
|
.unwrap_or(default.enhancements),
|
||||||
},
|
|
||||||
|
|
||||||
environment: match value.get("environment") {
|
environment: match value.get("environment") {
|
||||||
Some(value) => match value.as_object() {
|
Some(value) => match value.as_object() {
|
||||||
|
|
117
src/games/honkai/config/schema/game/paths.rs
Normal file
117
src/games/honkai/config/schema/game/paths.rs
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
use std::path::{Path, PathBuf};
|
||||||
|
|
||||||
|
use serde::{Serialize, Deserialize};
|
||||||
|
use serde_json::Value as JsonValue;
|
||||||
|
|
||||||
|
use anime_game_core::honkai::consts::GameEdition;
|
||||||
|
|
||||||
|
use crate::honkai::consts::launcher_dir;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
|
pub struct Paths {
|
||||||
|
pub global: PathBuf,
|
||||||
|
pub sea: PathBuf,
|
||||||
|
pub china: PathBuf,
|
||||||
|
pub taiwan: PathBuf,
|
||||||
|
pub korea: PathBuf,
|
||||||
|
pub japan: PathBuf
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Paths {
|
||||||
|
/// 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::Sea => self.sea.as_path(),
|
||||||
|
GameEdition::China => self.china.as_path(),
|
||||||
|
GameEdition::Taiwan => self.taiwan.as_path(),
|
||||||
|
GameEdition::Korea => self.korea.as_path(),
|
||||||
|
GameEdition::Japan => self.japan.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(concat!("Hon", "kai Imp", "act")),
|
||||||
|
sea: launcher_dir.join(concat!("Hon", "kai Imp", "act Sea")),
|
||||||
|
china: launcher_dir.join(concat!("Hon", "kai Imp", "act China")),
|
||||||
|
taiwan: launcher_dir.join(concat!("Hon", "kai Imp", "act Taiwan")),
|
||||||
|
korea: launcher_dir.join(concat!("Hon", "kai Imp", "act Korea")),
|
||||||
|
japan: launcher_dir.join(concat!("Hon", "kai Imp", "act Japan")),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&JsonValue> for Paths {
|
||||||
|
fn from(value: &JsonValue) -> Self {
|
||||||
|
let default = Self::default();
|
||||||
|
|
||||||
|
// SDK 1.8.13 and earlier
|
||||||
|
if value.is_string() {
|
||||||
|
let path = PathBuf::from(value.as_str().unwrap());
|
||||||
|
|
||||||
|
Self {
|
||||||
|
sea: path.parent()
|
||||||
|
.map(|value| value.join(concat!("Hon", "kai Imp", "act Sea")))
|
||||||
|
.unwrap_or(default.sea),
|
||||||
|
|
||||||
|
china: path.parent()
|
||||||
|
.map(|value| value.join(concat!("Hon", "kai Imp", "act China")))
|
||||||
|
.unwrap_or(default.china),
|
||||||
|
|
||||||
|
taiwan: path.parent()
|
||||||
|
.map(|value| value.join(concat!("Hon", "kai Imp", "act Taiwan")))
|
||||||
|
.unwrap_or(default.taiwan),
|
||||||
|
|
||||||
|
korea: path.parent()
|
||||||
|
.map(|value| value.join(concat!("Hon", "kai Imp", "act Korea")))
|
||||||
|
.unwrap_or(default.korea),
|
||||||
|
|
||||||
|
japan: path.parent()
|
||||||
|
.map(|value| value.join(concat!("Hon", "kai Imp", "act Japan")))
|
||||||
|
.unwrap_or(default.japan),
|
||||||
|
|
||||||
|
global: path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// SDK 1.9.0 and later
|
||||||
|
else {
|
||||||
|
Self {
|
||||||
|
global: value.get("global")
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or(default.global),
|
||||||
|
|
||||||
|
sea: value.get("sea")
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or(default.sea),
|
||||||
|
|
||||||
|
china: value.get("china")
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or(default.china),
|
||||||
|
|
||||||
|
taiwan: value.get("taiwan")
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or(default.taiwan),
|
||||||
|
|
||||||
|
korea: value.get("korea")
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or(default.korea),
|
||||||
|
|
||||||
|
japan: value.get("japan")
|
||||||
|
.and_then(JsonValue::as_str)
|
||||||
|
.map(PathBuf::from)
|
||||||
|
.unwrap_or(default.japan),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,8 +46,9 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
tracing::info!("Preparing to run the game");
|
tracing::info!("Preparing to run the game");
|
||||||
|
|
||||||
let config = Config::get()?;
|
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"));
|
return Err(anyhow::anyhow!("Game is not installed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
let mut folders = Folders {
|
let mut folders = Folders {
|
||||||
wine: config.game.wine.builds.join(&wine.name),
|
wine: config.game.wine.builds.join(&wine.name),
|
||||||
prefix: config.game.wine.prefix.clone(),
|
prefix: config.game.wine.prefix.clone(),
|
||||||
game: config.game.path.clone(),
|
game: game_path.clone(),
|
||||||
patch: config.patch.path.clone(),
|
patch: config.patch.path.clone(),
|
||||||
temp: config.launcher.temp.clone().unwrap_or(std::env::temp_dir())
|
temp: config.launcher.temp.clone().unwrap_or(std::env::temp_dir())
|
||||||
};
|
};
|
||||||
|
@ -221,7 +222,7 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
|
|
||||||
// We use real current dir here because sandboxed one
|
// We use real current dir here because sandboxed one
|
||||||
// obviously doesn't exist
|
// obviously doesn't exist
|
||||||
command.current_dir(&config.game.path)
|
command.current_dir(game_path)
|
||||||
.spawn()?.wait_with_output()?;
|
.spawn()?.wait_with_output()?;
|
||||||
|
|
||||||
#[cfg(feature = "discord-rpc")]
|
#[cfg(feature = "discord-rpc")]
|
||||||
|
|
|
@ -42,6 +42,7 @@ pub enum StateUpdating {
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct LauncherStateParams<F: Fn(StateUpdating)> {
|
pub struct LauncherStateParams<F: Fn(StateUpdating)> {
|
||||||
pub wine_prefix: PathBuf,
|
pub wine_prefix: PathBuf,
|
||||||
|
|
||||||
pub game_path: PathBuf,
|
pub game_path: PathBuf,
|
||||||
pub game_edition: GameEdition,
|
pub game_edition: GameEdition,
|
||||||
|
|
||||||
|
@ -138,7 +139,8 @@ impl LauncherState {
|
||||||
|
|
||||||
Self::get(LauncherStateParams {
|
Self::get(LauncherStateParams {
|
||||||
wine_prefix: config.get_wine_prefix_path(),
|
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(),
|
||||||
game_edition: config.launcher.edition,
|
game_edition: config.launcher.edition,
|
||||||
|
|
||||||
patch_folder: config.patch.path,
|
patch_folder: config.patch.path,
|
||||||
|
|
|
@ -16,25 +16,21 @@ impl From<&JsonValue> for Enhancements {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fsr: match value.get("fsr") {
|
fsr: value.get("fsr")
|
||||||
Some(value) => Fsr::from(value),
|
.map(Fsr::from)
|
||||||
None => default.fsr
|
.unwrap_or(default.fsr),
|
||||||
},
|
|
||||||
|
|
||||||
gamemode: match value.get("gamemode") {
|
gamemode: value.get("gamemode")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.gamemode),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.gamemode
|
.unwrap_or(default.gamemode),
|
||||||
},
|
|
||||||
|
|
||||||
hud: match value.get("hud") {
|
hud: value.get("hud")
|
||||||
Some(value) => HUD::from(value),
|
.map(HUD::from)
|
||||||
None => default.hud
|
.unwrap_or(default.hud),
|
||||||
},
|
|
||||||
|
|
||||||
gamescope: match value.get("gamescope") {
|
gamescope: value.get("gamescope")
|
||||||
Some(value) => Gamescope::from(value),
|
.map(Gamescope::from)
|
||||||
None => default.gamescope
|
.unwrap_or(default.gamescope)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,20 +59,17 @@ impl From<&JsonValue> for Game {
|
||||||
None => default.path
|
None => default.path
|
||||||
},
|
},
|
||||||
|
|
||||||
wine: match value.get("wine") {
|
wine: value.get("wine")
|
||||||
Some(value) => Wine::from(value),
|
.map(Wine::from)
|
||||||
None => default.wine
|
.unwrap_or(default.wine),
|
||||||
},
|
|
||||||
|
|
||||||
dxvk: match value.get("dxvk") {
|
dxvk: value.get("dxvk")
|
||||||
Some(value) => Dxvk::from(value),
|
.map(Dxvk::from)
|
||||||
None => default.dxvk
|
.unwrap_or(default.dxvk),
|
||||||
},
|
|
||||||
|
|
||||||
enhancements: match value.get("enhancements") {
|
enhancements: value.get("enhancements")
|
||||||
Some(value) => Enhancements::from(value),
|
.map(Enhancements::from)
|
||||||
None => default.enhancements
|
.unwrap_or(default.enhancements),
|
||||||
},
|
|
||||||
|
|
||||||
environment: match value.get("environment") {
|
environment: match value.get("environment") {
|
||||||
Some(value) => match value.as_object() {
|
Some(value) => match value.as_object() {
|
||||||
|
|
|
@ -16,25 +16,21 @@ impl From<&JsonValue> for Enhancements {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
fsr: match value.get("fsr") {
|
fsr: value.get("fsr")
|
||||||
Some(value) => Fsr::from(value),
|
.map(Fsr::from)
|
||||||
None => default.fsr
|
.unwrap_or(default.fsr),
|
||||||
},
|
|
||||||
|
|
||||||
gamemode: match value.get("gamemode") {
|
gamemode: value.get("gamemode")
|
||||||
Some(value) => value.as_bool().unwrap_or(default.gamemode),
|
.and_then(JsonValue::as_bool)
|
||||||
None => default.gamemode
|
.unwrap_or(default.gamemode),
|
||||||
},
|
|
||||||
|
|
||||||
hud: match value.get("hud") {
|
hud: value.get("hud")
|
||||||
Some(value) => HUD::from(value),
|
.map(HUD::from)
|
||||||
None => default.hud
|
.unwrap_or(default.hud),
|
||||||
},
|
|
||||||
|
|
||||||
gamescope: match value.get("gamescope") {
|
gamescope: value.get("gamescope")
|
||||||
Some(value) => Gamescope::from(value),
|
.map(Gamescope::from)
|
||||||
None => default.gamescope
|
.unwrap_or(default.gamescope)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,25 +52,21 @@ impl From<&JsonValue> for Game {
|
||||||
let default = Self::default();
|
let default = Self::default();
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
path: match value.get("path") {
|
path: value.get("path")
|
||||||
Some(value) => Paths::from(value),
|
.map(Paths::from)
|
||||||
None => default.path
|
.unwrap_or(default.path),
|
||||||
},
|
|
||||||
|
|
||||||
wine: match value.get("wine") {
|
wine: value.get("wine")
|
||||||
Some(value) => Wine::from(value),
|
.map(Wine::from)
|
||||||
None => default.wine
|
.unwrap_or(default.wine),
|
||||||
},
|
|
||||||
|
|
||||||
dxvk: match value.get("dxvk") {
|
dxvk: value.get("dxvk")
|
||||||
Some(value) => Dxvk::from(value),
|
.map(Dxvk::from)
|
||||||
None => default.dxvk
|
.unwrap_or(default.dxvk),
|
||||||
},
|
|
||||||
|
|
||||||
enhancements: match value.get("enhancements") {
|
enhancements: value.get("enhancements")
|
||||||
Some(value) => Enhancements::from(value),
|
.map(Enhancements::from)
|
||||||
None => default.enhancements
|
.unwrap_or(default.enhancements),
|
||||||
},
|
|
||||||
|
|
||||||
environment: match value.get("environment") {
|
environment: match value.get("environment") {
|
||||||
Some(value) => match value.as_object() {
|
Some(value) => match value.as_object() {
|
||||||
|
|
|
@ -19,7 +19,7 @@ impl Paths {
|
||||||
pub fn for_edition(&self, edition: impl Into<GameEdition>) -> &Path {
|
pub fn for_edition(&self, edition: impl Into<GameEdition>) -> &Path {
|
||||||
match edition.into() {
|
match edition.into() {
|
||||||
GameEdition::Global => self.global.as_path(),
|
GameEdition::Global => self.global.as_path(),
|
||||||
GameEdition::China => self.china.as_path()
|
GameEdition::China => self.china.as_path()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ impl Default for Paths {
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
global: launcher_dir.join("HSR"),
|
global: launcher_dir.join("HSR"),
|
||||||
china: launcher_dir.join("HSR China")
|
china: launcher_dir.join("HSR China")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue