feat(star-rail): integrated jadeite patch
This commit is contained in:
parent
60d800a23d
commit
947b243245
4 changed files with 53 additions and 73 deletions
|
@ -9,7 +9,7 @@ edition = "2021"
|
|||
|
||||
[dependencies.anime-game-core]
|
||||
git = "https://github.com/an-anime-team/anime-game-core"
|
||||
tag = "1.11.8"
|
||||
tag = "1.12.0"
|
||||
features = ["all"]
|
||||
|
||||
# path = "../anime-game-core" # ! for dev purposes only
|
||||
|
@ -35,6 +35,10 @@ star-rail = ["anime-game-core/star-rail"]
|
|||
honkai = ["anime-game-core/honkai"]
|
||||
pgr = ["anime-game-core/pgr"]
|
||||
|
||||
genshin-patch = ["anime-game-core/patch-dawn"]
|
||||
star-rail-patch = ["anime-game-core/patch-jadeite"]
|
||||
honkai-patch = ["anime-game-core/patch-jadeite"]
|
||||
|
||||
# Common features
|
||||
states = []
|
||||
config = ["dep:serde", "dep:serde_json", "dep:enum-ordinalize"]
|
||||
|
|
|
@ -7,9 +7,7 @@ use crate::star_rail::consts::launcher_dir;
|
|||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Patch {
|
||||
pub path: PathBuf,
|
||||
pub servers: Vec<String>,
|
||||
pub root: bool
|
||||
pub path: PathBuf
|
||||
}
|
||||
|
||||
impl Default for Patch {
|
||||
|
@ -18,15 +16,7 @@ impl Default for Patch {
|
|||
let launcher_dir = launcher_dir().expect("Failed to get launcher dir");
|
||||
|
||||
Self {
|
||||
path: launcher_dir.join("patch"),
|
||||
|
||||
servers: vec![
|
||||
String::from("https://codeberg.org/an-anime-team/astra"),
|
||||
String::from("https://notabug.org/mkrsym1/astra")
|
||||
],
|
||||
|
||||
// Disable root requirement for patching if we're running launcher in flatpak
|
||||
root: !PathBuf::from("/.flatpak-info").exists()
|
||||
path: launcher_dir.join("patch")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -36,35 +26,9 @@ impl From<&JsonValue> for Patch {
|
|||
let default = Self::default();
|
||||
|
||||
Self {
|
||||
path: match value.get("path") {
|
||||
Some(value) => match value.as_str() {
|
||||
Some(value) => PathBuf::from(value),
|
||||
path: match value.get("path").and_then(|path| path.as_str()).map(PathBuf::from) {
|
||||
Some(path) => path,
|
||||
None => default.path
|
||||
},
|
||||
None => default.path
|
||||
},
|
||||
|
||||
servers: match value.get("servers") {
|
||||
Some(value) => match value.as_array() {
|
||||
Some(values) => {
|
||||
let mut servers = Vec::new();
|
||||
|
||||
for value in values {
|
||||
if let Some(server) = value.as_str() {
|
||||
servers.push(server.to_string());
|
||||
}
|
||||
}
|
||||
|
||||
servers
|
||||
},
|
||||
None => default.servers
|
||||
},
|
||||
None => default.servers
|
||||
},
|
||||
|
||||
root: match value.get("root") {
|
||||
Some(value) => value.as_bool().unwrap_or(default.root),
|
||||
None => default.root
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ struct Folders {
|
|||
pub wine: PathBuf,
|
||||
pub prefix: PathBuf,
|
||||
pub game: PathBuf,
|
||||
pub patch: PathBuf,
|
||||
pub temp: PathBuf
|
||||
}
|
||||
|
||||
|
@ -34,6 +35,7 @@ fn replace_keywords(command: impl ToString, folders: &Folders) -> String {
|
|||
.replace("%temp%", folders.game.to_str().unwrap())
|
||||
.replace("%launcher%", &consts::launcher_dir().unwrap().to_string_lossy())
|
||||
.replace("%game%", folders.temp.to_str().unwrap())
|
||||
.replace("%patch%", folders.patch.to_str().unwrap())
|
||||
}
|
||||
|
||||
/// Try to run the game
|
||||
|
@ -60,6 +62,7 @@ pub fn run() -> anyhow::Result<()> {
|
|||
wine: config.game.wine.builds.join(&wine.name),
|
||||
prefix: config.game.wine.prefix.clone(),
|
||||
game: game_path.clone(),
|
||||
patch: config.patch.path.clone(),
|
||||
temp: config.launcher.temp.clone().unwrap_or(std::env::temp_dir())
|
||||
};
|
||||
|
||||
|
@ -92,7 +95,7 @@ pub fn run() -> anyhow::Result<()> {
|
|||
windows_command += " ";
|
||||
}
|
||||
|
||||
windows_command += "launch.bat ";
|
||||
windows_command += &format!("'{}/jadeite.exe' 'Z:\\{}/StarRail.exe' ", folders.patch.to_string_lossy(), folders.game.to_string_lossy());
|
||||
|
||||
if config.game.wine.borderless {
|
||||
windows_command += "-screen-fullscreen 0 -popupwindow ";
|
||||
|
@ -124,10 +127,13 @@ pub fn run() -> anyhow::Result<()> {
|
|||
folders.game.to_str().unwrap()
|
||||
);
|
||||
|
||||
let bwrap = format!("{bwrap} --bind '{}' /tmp/sandbox/patch", folders.patch.to_string_lossy());
|
||||
|
||||
let sandboxed_folders = Folders {
|
||||
wine: PathBuf::from("/tmp/sandbox/wine"),
|
||||
prefix: PathBuf::from("/tmp/sandbox/prefix"),
|
||||
game: PathBuf::from("/tmp/sandbox/game"),
|
||||
patch: PathBuf::from("/tmp/sandbox/patch"),
|
||||
temp: PathBuf::from("/tmp")
|
||||
};
|
||||
|
||||
|
@ -135,6 +141,14 @@ pub fn run() -> anyhow::Result<()> {
|
|||
.replace(folders.wine.to_str().unwrap(), sandboxed_folders.wine.to_str().unwrap())
|
||||
.replace(folders.prefix.to_str().unwrap(), sandboxed_folders.prefix.to_str().unwrap())
|
||||
.replace(folders.game.to_str().unwrap(), sandboxed_folders.game.to_str().unwrap())
|
||||
.replace(folders.patch.to_str().unwrap(), sandboxed_folders.patch.to_str().unwrap())
|
||||
.replace(folders.temp.to_str().unwrap(), sandboxed_folders.temp.to_str().unwrap());
|
||||
|
||||
windows_command = windows_command
|
||||
.replace(folders.wine.to_str().unwrap(), sandboxed_folders.wine.to_str().unwrap())
|
||||
.replace(folders.prefix.to_str().unwrap(), sandboxed_folders.prefix.to_str().unwrap())
|
||||
.replace(folders.game.to_str().unwrap(), sandboxed_folders.game.to_str().unwrap())
|
||||
.replace(folders.patch.to_str().unwrap(), sandboxed_folders.patch.to_str().unwrap())
|
||||
.replace(folders.temp.to_str().unwrap(), sandboxed_folders.temp.to_str().unwrap());
|
||||
|
||||
bash_command = format!("{bwrap} --chdir /tmp/sandbox/game -- {bash_command}");
|
||||
|
|
|
@ -10,16 +10,21 @@ use crate::star_rail::config::Config;
|
|||
pub enum LauncherState {
|
||||
Launch,
|
||||
|
||||
/// Always contains `VersionDiff::Predownload`
|
||||
PredownloadAvailable(VersionDiff),
|
||||
PatchNotVerified,
|
||||
PatchBroken,
|
||||
PatchUnsafe,
|
||||
|
||||
MainPatchAvailable(MainPatch),
|
||||
PatchNotInstalled,
|
||||
PatchUpdateAvailable,
|
||||
|
||||
#[cfg(feature = "components")]
|
||||
WineNotInstalled,
|
||||
|
||||
PrefixNotExists,
|
||||
|
||||
/// Always contains `VersionDiff::Predownload`
|
||||
PredownloadAvailable(VersionDiff),
|
||||
|
||||
// Always contains `VersionDiff::Diff`
|
||||
GameUpdateAvailable(VersionDiff),
|
||||
|
||||
|
@ -42,8 +47,6 @@ pub struct LauncherStateParams<F: Fn(StateUpdating)> {
|
|||
pub game_edition: GameEdition,
|
||||
|
||||
pub wine_prefix: PathBuf,
|
||||
|
||||
pub patch_servers: Vec<String>,
|
||||
pub patch_folder: PathBuf,
|
||||
|
||||
pub status_updater: F
|
||||
|
@ -65,29 +68,20 @@ impl LauncherState {
|
|||
let diff = game.try_get_diff()?;
|
||||
|
||||
match diff {
|
||||
VersionDiff::Latest { .. } | VersionDiff::Predownload { .. } => {
|
||||
VersionDiff::Latest { version, .. } | VersionDiff::Predownload { current: version, .. } => {
|
||||
// Check game patch status
|
||||
(params.status_updater)(StateUpdating::Patch);
|
||||
|
||||
let patch = Patch::new(¶ms.patch_folder, params.game_edition);
|
||||
|
||||
// Sync local patch folder with remote if needed
|
||||
// TODO: maybe I shouldn't do it here?
|
||||
if patch.is_sync(¶ms.patch_servers)?.is_none() {
|
||||
for server in ¶ms.patch_servers {
|
||||
if patch.sync(server).is_ok() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !jadeite::is_installed(¶ms.patch_folder) {
|
||||
return Ok(Self::PatchNotInstalled);
|
||||
}
|
||||
|
||||
// Check the main patch
|
||||
let main_patch = patch.main_patch()?;
|
||||
|
||||
if !main_patch.is_applied(¶ms.game_path)? {
|
||||
return Ok(Self::MainPatchAvailable(main_patch));
|
||||
if jadeite::get_latest()?.version > jadeite::get_version(params.patch_folder)? {
|
||||
return Ok(Self::PatchUpdateAvailable);
|
||||
}
|
||||
|
||||
match jadeite::get_metadata()?.hsr.global.get_status(version) {
|
||||
JadeitePatchStatusVariant::Verified => {
|
||||
// Check if update predownload available
|
||||
if let VersionDiff::Predownload { .. } = diff {
|
||||
Ok(Self::PredownloadAvailable(diff))
|
||||
|
@ -99,6 +93,12 @@ impl LauncherState {
|
|||
}
|
||||
}
|
||||
|
||||
JadeitePatchStatusVariant::Unverified => Ok(Self::PatchNotVerified),
|
||||
JadeitePatchStatusVariant::Broken => Ok(Self::PatchBroken),
|
||||
JadeitePatchStatusVariant::Unsafe => Ok(Self::PatchUnsafe)
|
||||
}
|
||||
}
|
||||
|
||||
VersionDiff::Diff { .. } => Ok(Self::GameUpdateAvailable(diff)),
|
||||
VersionDiff::Outdated { .. } => Ok(Self::GameOutdated(diff)),
|
||||
VersionDiff::NotInstalled { .. } => Ok(Self::GameNotInstalled(diff))
|
||||
|
@ -126,8 +126,6 @@ impl LauncherState {
|
|||
game_edition: config.launcher.edition,
|
||||
|
||||
wine_prefix: config.get_wine_prefix_path(),
|
||||
|
||||
patch_servers: config.patch.servers,
|
||||
patch_folder: config.patch.path,
|
||||
|
||||
status_updater
|
||||
|
|
Loading…
Reference in a new issue