mirror of
https://github.com/an-anime-team/an-anime-game-launcher.git
synced 2024-11-22 12:56:06 +03:00
Changed config file format and struture
- added `Config::try_get_wine_executable` method - fixed launher freezing when running the game
This commit is contained in:
parent
1eed56e53a
commit
8bec171c5d
4 changed files with 139 additions and 32 deletions
|
@ -14,6 +14,6 @@ libadwaita = "0.1"
|
||||||
anime-game-core = { path = "anime-game-core", features = ["all"] }
|
anime-game-core = { path = "anime-game-core", features = ["all"] }
|
||||||
|
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
toml = "0.5.9"
|
serde_json = "1.0"
|
||||||
|
|
||||||
dirs = "4.0.0"
|
dirs = "4.0.0"
|
||||||
|
|
|
@ -5,7 +5,7 @@ use std::io::{Error, ErrorKind, Write};
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
|
|
||||||
use super::consts::config_file;
|
use super::consts::*;
|
||||||
|
|
||||||
pub fn get() -> Result<Config, Error> {
|
pub fn get() -> Result<Config, Error> {
|
||||||
match config_file() {
|
match config_file() {
|
||||||
|
@ -13,13 +13,13 @@ pub fn get() -> Result<Config, Error> {
|
||||||
// Try to read config if the file exists
|
// Try to read config if the file exists
|
||||||
if Path::new(&path).exists() {
|
if Path::new(&path).exists() {
|
||||||
let mut file = File::open(path)?;
|
let mut file = File::open(path)?;
|
||||||
let mut toml = String::new();
|
let mut json = String::new();
|
||||||
|
|
||||||
file.read_to_string(&mut toml)?;
|
file.read_to_string(&mut json)?;
|
||||||
|
|
||||||
match toml::from_str::<Config>(&toml) {
|
match serde_json::from_str::<Config>(&json) {
|
||||||
Ok(toml) => Ok(toml),
|
Ok(json) => Ok(json),
|
||||||
Err(err) => Err(Error::new(ErrorKind::InvalidData, format!("Failed to decode data from toml format: {}", err.to_string())))
|
Err(err) => Err(Error::new(ErrorKind::InvalidData, format!("Failed to decode data from json format: {}", err.to_string())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,13 +39,13 @@ pub fn update(config: Config) -> Result<(), Error> {
|
||||||
Some(path) => {
|
Some(path) => {
|
||||||
let mut file = File::create(&path)?;
|
let mut file = File::create(&path)?;
|
||||||
|
|
||||||
match toml::to_string(&config) {
|
match serde_json::to_string_pretty(&config) {
|
||||||
Ok(toml) => {
|
Ok(json) => {
|
||||||
file.write_all(&mut toml.as_bytes())?;
|
file.write_all(&mut json.as_bytes())?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
},
|
},
|
||||||
Err(err) => Err(Error::new(ErrorKind::InvalidData, format!("Failed to encode data into toml format: {}", err.to_string())))
|
Err(err) => Err(Error::new(ErrorKind::InvalidData, format!("Failed to encode data into json format: {}", err.to_string())))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => Err(Error::new(ErrorKind::NotFound, format!("Failed to get config file path")))
|
None => Err(Error::new(ErrorKind::NotFound, format!("Failed to get config file path")))
|
||||||
|
@ -54,35 +54,137 @@ pub fn update(config: Config) -> Result<(), Error> {
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub paths: Paths,
|
pub launcher: Launcher,
|
||||||
pub patch: Patch,
|
pub game: Game,
|
||||||
pub wine: Wine
|
pub patch: Patch
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
impl Config {
|
||||||
pub struct Paths {
|
/// Try to get a path to the wine executable based on `game.wine.builds` and `game.wine.selected`
|
||||||
pub game: String,
|
pub fn try_get_wine_executable(&self) -> Option<String> {
|
||||||
pub patch: String
|
match &self.game.wine.selected {
|
||||||
|
Some(selected) => {
|
||||||
|
// Most of wine builds
|
||||||
|
let path = format!("{}/{}/bin/wine", &self.game.wine.builds, &selected);
|
||||||
|
|
||||||
|
if Path::new(&path).exists() {
|
||||||
|
return Some(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Proton-based builds
|
||||||
|
let path = format!("{}/{}/files/bin/wine", &self.game.wine.builds, &selected);
|
||||||
|
|
||||||
|
if Path::new(&path).exists() {
|
||||||
|
return Some(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
// ????
|
||||||
|
None
|
||||||
|
},
|
||||||
|
None => None
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize, Default)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Launcher {
|
||||||
|
pub language: String
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Launcher {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
language: String::from("en-us")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Patch {
|
pub struct Patch {
|
||||||
pub hosts: Vec<String>
|
pub path: String,
|
||||||
|
pub servers: Vec<String>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Patch {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
path: match launcher_dir() {
|
||||||
|
Some(dir) => format!("{}/patch", dir),
|
||||||
|
None => String::new()
|
||||||
|
},
|
||||||
|
servers: Vec::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Game {
|
||||||
|
pub path: String,
|
||||||
|
pub voices: Vec<String>,
|
||||||
|
pub wine: Wine,
|
||||||
|
pub enhancements: Enhancements,
|
||||||
|
pub environment: HashMap<String, String>
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Game {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
path: match launcher_dir() {
|
||||||
|
Some(dir) => format!("{}/game/drive_c/Program Files/Genshin Impact", dir),
|
||||||
|
None => String::new()
|
||||||
|
},
|
||||||
|
voices: vec![
|
||||||
|
String::from("en-us")
|
||||||
|
],
|
||||||
|
wine: Wine::default(),
|
||||||
|
enhancements: Enhancements::default(),
|
||||||
|
environment: HashMap::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
pub struct Wine {
|
pub struct Wine {
|
||||||
pub prefix: String,
|
pub prefix: String,
|
||||||
pub executable: String,
|
pub builds: String,
|
||||||
pub environment: HashMap<String, String>
|
pub selected: Option<String>,
|
||||||
|
pub sync: String
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Wine {
|
impl Default for Wine {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
prefix: String::new(),
|
prefix: match launcher_dir() {
|
||||||
executable: String::new(),
|
Some(dir) => format!("{}/game", dir),
|
||||||
environment: HashMap::new()
|
None => String::new()
|
||||||
|
},
|
||||||
|
builds: match launcher_dir() {
|
||||||
|
Some(dir) => format!("{}/runners", dir),
|
||||||
|
None => String::new()
|
||||||
|
},
|
||||||
|
selected: None,
|
||||||
|
sync: String::from("esync")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize, Default)]
|
||||||
|
pub struct Enhancements {
|
||||||
|
pub fsr: Fsr,
|
||||||
|
pub gamemode: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
pub struct Fsr {
|
||||||
|
pub strength: u8,
|
||||||
|
pub enabled: bool
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for Fsr {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
strength: 3,
|
||||||
|
enabled: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub fn config_file() -> Option<String> {
|
||||||
Some(value) => value.clone(),
|
Some(value) => value.clone(),
|
||||||
None => {
|
None => {
|
||||||
let value = match launcher_dir() {
|
let value = match launcher_dir() {
|
||||||
Some(dir) => Some(format!("{}/config.toml", dir)),
|
Some(dir) => Some(format!("{}/config.json", dir)),
|
||||||
None => None
|
None => None
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -7,16 +7,21 @@ use super::config;
|
||||||
pub fn run() -> Result<(), Error> {
|
pub fn run() -> Result<(), Error> {
|
||||||
let config = config::get()?;
|
let config = config::get()?;
|
||||||
|
|
||||||
if Path::new(&config.paths.game).exists() {
|
if !Path::new(&config.game.path).exists() {
|
||||||
return Err(Error::new(ErrorKind::Other, "Game is not installed"));
|
return Err(Error::new(ErrorKind::Other, "Game is not installed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
Command::new(config.wine.executable)
|
let wine_executable = match config.try_get_wine_executable() {
|
||||||
.env("WINEPREFIX", &config.wine.prefix)
|
Some(path) => path,
|
||||||
.envs(config.wine.environment)
|
None => return Err(Error::new(ErrorKind::Other, "Couldn't find wine executable"))
|
||||||
.current_dir(config.paths.game)
|
};
|
||||||
|
|
||||||
|
Command::new(wine_executable)
|
||||||
|
.env("WINEPREFIX", config.game.wine.prefix)
|
||||||
|
.envs(config.game.environment)
|
||||||
|
.current_dir(config.game.path)
|
||||||
.arg("launcher.bat")
|
.arg("launcher.bat")
|
||||||
.output()?;
|
.spawn()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue