Merge pull request #8 from mkrsym1/new-fps-unlocker
Change FPS unlocker to our own
This commit is contained in:
commit
97349fcfc7
4 changed files with 15 additions and 129 deletions
|
@ -1,15 +1,10 @@
|
||||||
use serde::{Serialize, Deserialize};
|
use serde::{Serialize, Deserialize};
|
||||||
use serde_json::Value as JsonValue;
|
use serde_json::Value as JsonValue;
|
||||||
|
|
||||||
use crate::config::schema_blanks::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct Config {
|
pub struct Config {
|
||||||
pub fps: u64, // TODO: Fps enum
|
pub fps: u64, // TODO: Fps enum
|
||||||
pub power_saving: bool,
|
pub interval: u64
|
||||||
pub monitor: u64,
|
|
||||||
pub window_mode: WindowMode,
|
|
||||||
pub priority: u64
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Config {
|
impl Default for Config {
|
||||||
|
@ -17,10 +12,7 @@ impl Default for Config {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
fps: 120,
|
fps: 120,
|
||||||
power_saving: false,
|
interval: 5000
|
||||||
monitor: 1,
|
|
||||||
window_mode: WindowMode::default(),
|
|
||||||
priority: 3
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -35,24 +27,9 @@ impl From<&JsonValue> for Config {
|
||||||
None => default.fps
|
None => default.fps
|
||||||
},
|
},
|
||||||
|
|
||||||
power_saving: match value.get("power_saving") {
|
interval: match value.get("interval") {
|
||||||
Some(value) => value.as_bool().unwrap_or(default.power_saving),
|
Some(value) => value.as_u64().unwrap_or(default.interval),
|
||||||
None => default.power_saving
|
None => default.interval
|
||||||
},
|
|
||||||
|
|
||||||
monitor: match value.get("monitor") {
|
|
||||||
Some(value) => value.as_u64().unwrap_or(default.monitor),
|
|
||||||
None => default.monitor
|
|
||||||
},
|
|
||||||
|
|
||||||
window_mode: match value.get("window_mode") {
|
|
||||||
Some(value) => WindowMode::from(value),
|
|
||||||
None => default.window_mode
|
|
||||||
},
|
|
||||||
|
|
||||||
priority: match value.get("priority") {
|
|
||||||
Some(value) => value.as_u64().unwrap_or(default.priority),
|
|
||||||
None => default.priority
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,13 +4,9 @@ use md5::{Md5, Digest};
|
||||||
|
|
||||||
use anime_game_core::installer::downloader::Downloader;
|
use anime_game_core::installer::downloader::Downloader;
|
||||||
|
|
||||||
use super::config::schema::prelude::FpsUnlockerConfig;
|
|
||||||
|
|
||||||
pub mod config_schema;
|
|
||||||
|
|
||||||
const LATEST_INFO: (&str, &str) = (
|
const LATEST_INFO: (&str, &str) = (
|
||||||
"cff81830eebd3566d51b73ffaa444035",
|
"53cb34d292d6b1dd1d8310318fe49bad",
|
||||||
"https://github.com/34736384/genshin-fps-unlock/releases/download/v2.2.0/unlockfps_clr.exe"
|
"https://codeberg.org/mkrsym1/fpsunlock/releases/download/v1.0.2/fpsunlock.exe"
|
||||||
);
|
);
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
@ -22,13 +18,13 @@ impl FpsUnlocker {
|
||||||
/// Get FpsUnlocker from its containment directory
|
/// Get FpsUnlocker from its containment directory
|
||||||
///
|
///
|
||||||
/// Returns
|
/// Returns
|
||||||
/// - `Err(..)` if failed to read `unlocker.exe` file
|
/// - `Err(..)` if failed to read `fpsunlock.exe` file
|
||||||
/// - `Ok(None)` if version is not latest
|
/// - `Ok(None)` if version is not latest
|
||||||
/// - `Ok(..)` if version is latest
|
/// - `Ok(..)` if version is latest
|
||||||
pub fn from_dir<T: Into<PathBuf> + std::fmt::Debug>(dir: T) -> anyhow::Result<Option<Self>> {
|
pub fn from_dir<T: Into<PathBuf> + std::fmt::Debug>(dir: T) -> anyhow::Result<Option<Self>> {
|
||||||
let dir = dir.into();
|
let dir = dir.into();
|
||||||
|
|
||||||
let hash = format!("{:x}", Md5::digest(std::fs::read(dir.join("unlocker.exe"))?));
|
let hash = format!("{:x}", Md5::digest(std::fs::read(dir.join("fpsunlock.exe"))?));
|
||||||
|
|
||||||
Ok(if hash == LATEST_INFO.0 {
|
Ok(if hash == LATEST_INFO.0 {
|
||||||
Some(Self { dir })
|
Some(Self { dir })
|
||||||
|
@ -51,7 +47,7 @@ impl FpsUnlocker {
|
||||||
std::fs::create_dir_all(&dir)?;
|
std::fs::create_dir_all(&dir)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
match downloader.download(dir.join("unlocker.exe"), |_, _| {}) {
|
match downloader.download(dir.join("fpsunlock.exe"), |_, _| {}) {
|
||||||
Ok(_) => Ok(Self { dir }),
|
Ok(_) => Ok(Self { dir }),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
tracing::error!("Downloading failed: {err}");
|
tracing::error!("Downloading failed: {err}");
|
||||||
|
@ -68,24 +64,11 @@ impl FpsUnlocker {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_binary_in<T: Into<PathBuf>>(dir: T) -> PathBuf {
|
pub fn get_binary_in<T: Into<PathBuf>>(dir: T) -> PathBuf {
|
||||||
dir.into().join("unlocker.exe")
|
dir.into().join("fpsunlock.exe")
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn dir(&self) -> &PathBuf {
|
pub fn dir(&self) -> &PathBuf {
|
||||||
&self.dir
|
&self.dir
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generate and save FPS unlocker config file to the game's directory
|
|
||||||
#[tracing::instrument(level = "debug", ret)]
|
|
||||||
pub fn update_config(&self, config: FpsUnlockerConfig) -> anyhow::Result<()> {
|
|
||||||
tracing::debug!("Updating FPS unlocker config");
|
|
||||||
|
|
||||||
let config = config_schema::ConfigSchema::from_config(config);
|
|
||||||
|
|
||||||
Ok(std::fs::write(
|
|
||||||
self.dir.join("fps_config.json"),
|
|
||||||
config.json()?
|
|
||||||
)?)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,69 +0,0 @@
|
||||||
use serde::{Serialize, Deserialize};
|
|
||||||
|
|
||||||
use crate::config::schema_blanks::prelude::*;
|
|
||||||
use super::FpsUnlockerConfig;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
|
||||||
#[allow(non_snake_case)]
|
|
||||||
pub struct ConfigSchema {
|
|
||||||
pub DllList: Vec<String>,
|
|
||||||
pub Priority: u64,
|
|
||||||
pub MonitorNum: u64,
|
|
||||||
pub CustomResY: u64,
|
|
||||||
pub CustomResX: u64,
|
|
||||||
pub FPSTarget: u64,
|
|
||||||
pub UsePowerSave: bool,
|
|
||||||
pub StartMinimized: bool,
|
|
||||||
pub IsExclusiveFullscreen: bool,
|
|
||||||
pub UseCustomRes: bool,
|
|
||||||
pub Fullscreen: bool,
|
|
||||||
pub PopupWindow: bool,
|
|
||||||
pub AutoClose: bool,
|
|
||||||
pub AutoDisableVSync: bool,
|
|
||||||
pub AutoStart: bool,
|
|
||||||
pub GamePath: Option<String>
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for ConfigSchema {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
DllList: vec![],
|
|
||||||
Priority: 3,
|
|
||||||
MonitorNum: 1,
|
|
||||||
CustomResY: 1080,
|
|
||||||
CustomResX: 1920,
|
|
||||||
FPSTarget: 120,
|
|
||||||
UsePowerSave: false,
|
|
||||||
IsExclusiveFullscreen: false,
|
|
||||||
UseCustomRes: false,
|
|
||||||
Fullscreen: false,
|
|
||||||
PopupWindow: false,
|
|
||||||
AutoDisableVSync: true,
|
|
||||||
GamePath: None,
|
|
||||||
|
|
||||||
// Launcher-specific settings
|
|
||||||
AutoStart: true,
|
|
||||||
AutoClose: true,
|
|
||||||
StartMinimized: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl ConfigSchema {
|
|
||||||
pub fn from_config(config: FpsUnlockerConfig) -> Self {
|
|
||||||
Self {
|
|
||||||
FPSTarget: config.fps,
|
|
||||||
UsePowerSave: config.power_saving,
|
|
||||||
PopupWindow: config.window_mode == WindowMode::Popup,
|
|
||||||
Fullscreen: config.window_mode == WindowMode::Fullscreen,
|
|
||||||
MonitorNum: config.monitor,
|
|
||||||
Priority: config.priority,
|
|
||||||
|
|
||||||
..Self::default()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn json(&self) -> serde_json::Result<String> {
|
|
||||||
serde_json::to_string(self)
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -89,8 +89,7 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
|
|
||||||
// Prepare fps unlocker
|
// Prepare fps unlocker
|
||||||
// 1) Download if needed
|
// 1) Download if needed
|
||||||
// 2) Generate config file
|
// 2) Generate fps_unlocker.bat
|
||||||
// 3) Generate fpsunlocker.bat from launcher.bat
|
|
||||||
|
|
||||||
#[cfg(feature = "fps-unlocker")]
|
#[cfg(feature = "fps-unlocker")]
|
||||||
if config.game.enhancements.fps_unlocker.enabled {
|
if config.game.enhancements.fps_unlocker.enabled {
|
||||||
|
@ -115,14 +114,10 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Generate FPS unlocker config file
|
|
||||||
if let Err(err) = unlocker.update_config(config.game.enhancements.fps_unlocker.config) {
|
|
||||||
return Err(anyhow::anyhow!("Failed to update FPS unlocker config: {err}"));
|
|
||||||
}
|
|
||||||
|
|
||||||
// If patch applying is disabled, then game_executable is either GenshinImpact.exe or YuanShen.exe
|
// If patch applying is disabled, then game_executable is either GenshinImpact.exe or YuanShen.exe
|
||||||
// so we don't need to check it here
|
// so we don't need to check it here
|
||||||
std::fs::write(game_path.join("fps_unlocker.bat"), format!("start {game_executable} %*\n\nZ:\ncd \"{}\"\nstart unlocker.exe", unlocker.dir().to_string_lossy()))?;
|
let unlocker_config = &config.game.enhancements.fps_unlocker.config;
|
||||||
|
std::fs::write(game_path.join("fps_unlocker.bat"), format!("start {game_executable} %*\n\nZ:\ncd \"{}\"\nstart fpsunlock.exe {} {}", unlocker.dir().to_string_lossy(), unlocker_config.fps, unlocker_config.interval))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate `config.ini` if environment emulation feature is presented
|
// Generate `config.ini` if environment emulation feature is presented
|
||||||
|
@ -314,7 +309,7 @@ pub fn run() -> anyhow::Result<()> {
|
||||||
let output = Command::new("ps").arg("-A").stdout(Stdio::piped()).output()?;
|
let output = Command::new("ps").arg("-A").stdout(Stdio::piped()).output()?;
|
||||||
let output = String::from_utf8_lossy(&output.stdout);
|
let output = String::from_utf8_lossy(&output.stdout);
|
||||||
|
|
||||||
if !output.contains("GenshinImpact.e") && !output.contains("YuanShen.exe") && !output.contains("unlocker.exe") {
|
if !output.contains("GenshinImpact.e") && !output.contains("YuanShen.exe") && !output.contains("fpsunlock.exe") {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue