feat: initial honkers support
This commit is contained in:
parent
77c8b6d0ff
commit
427de5e802
6 changed files with 72 additions and 107 deletions
20
Cargo.toml
20
Cargo.toml
|
@ -7,11 +7,11 @@ readme = "README.md"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
[dependencies.anime-game-core]
|
[dependencies.anime-game-core]
|
||||||
git = "https://github.com/an-anime-team/anime-game-core"
|
# git = "https://github.com/an-anime-team/anime-game-core"
|
||||||
tag = "1.6.2"
|
# tag = "1.6.2"
|
||||||
features = ["genshin", "all"]
|
features = ["all"]
|
||||||
|
|
||||||
# path = "../anime-game-core" # ! for dev purposes only
|
path = "../anime-game-core" # ! for dev purposes only
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
anyhow = { version = "1.0", features = ["backtrace"] }
|
anyhow = { version = "1.0", features = ["backtrace"] }
|
||||||
|
@ -28,13 +28,19 @@ md-5 = { version = "0.10", features = ["asm"], optional = true }
|
||||||
discord-rich-presence = { version = "0.2.3", optional = true }
|
discord-rich-presence = { version = "0.2.3", optional = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
|
genshin = ["anime-game-core/genshin"]
|
||||||
|
honkai = ["anime-game-core/honkai"]
|
||||||
|
|
||||||
|
# Common features
|
||||||
states = []
|
states = []
|
||||||
config = ["dep:serde", "dep:serde_json", "dep:enum-ordinalize"]
|
config = ["dep:serde", "dep:serde_json", "dep:enum-ordinalize"]
|
||||||
components = ["dep:wincompatlib", "dep:lazy_static"]
|
components = ["dep:wincompatlib", "dep:lazy_static"]
|
||||||
game = ["components", "config"]
|
game = ["components", "config"]
|
||||||
fps-unlocker = ["dep:md-5"]
|
|
||||||
discord-rpc = ["dep:discord-rich-presence"]
|
discord-rpc = ["dep:discord-rich-presence"]
|
||||||
environment-emulation = []
|
|
||||||
|
|
||||||
all = ["states", "config", "components", "game", "fps-unlocker", "discord-rpc", "environment-emulation"]
|
# Genshin-specific features
|
||||||
|
environment-emulation = []
|
||||||
|
fps-unlocker = ["dep:md-5"]
|
||||||
|
|
||||||
|
all = ["states", "config", "components", "game", "discord-rpc", "environment-emulation", "fps-unlocker"]
|
||||||
default = ["all"]
|
default = ["all"]
|
||||||
|
|
5
src/genshin/mod.rs
Normal file
5
src/genshin/mod.rs
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
#[cfg(feature = "states")]
|
||||||
|
pub mod states;
|
||||||
|
|
||||||
|
#[cfg(feature = "environment-emulation")]
|
||||||
|
pub mod env_emulation;
|
44
src/genshin/states.rs
Normal file
44
src/genshin/states.rs
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
// TODO
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
|
pub enum LauncherState {
|
||||||
|
Launch,
|
||||||
|
|
||||||
|
/// Always contains `VersionDiff::Predownload`
|
||||||
|
PredownloadAvailable {
|
||||||
|
game: VersionDiff,
|
||||||
|
voices: Vec<VersionDiff>
|
||||||
|
},
|
||||||
|
|
||||||
|
FolderMigrationRequired {
|
||||||
|
from: PathBuf,
|
||||||
|
to: PathBuf,
|
||||||
|
cleanup_folder: Option<PathBuf>
|
||||||
|
},
|
||||||
|
|
||||||
|
UnityPlayerPatchAvailable(UnityPlayerPatch),
|
||||||
|
XluaPatchAvailable(XluaPatch),
|
||||||
|
|
||||||
|
#[cfg(feature = "components")]
|
||||||
|
WineNotInstalled,
|
||||||
|
|
||||||
|
PrefixNotExists,
|
||||||
|
|
||||||
|
// Always contains `VersionDiff::Diff`
|
||||||
|
VoiceUpdateAvailable(VersionDiff),
|
||||||
|
|
||||||
|
/// Always contains `VersionDiff::Outdated`
|
||||||
|
VoiceOutdated(VersionDiff),
|
||||||
|
|
||||||
|
/// Always contains `VersionDiff::NotInstalled`
|
||||||
|
VoiceNotInstalled(VersionDiff),
|
||||||
|
|
||||||
|
// Always contains `VersionDiff::Diff`
|
||||||
|
GameUpdateAvailable(VersionDiff),
|
||||||
|
|
||||||
|
/// Always contains `VersionDiff::Outdated`
|
||||||
|
GameOutdated(VersionDiff),
|
||||||
|
|
||||||
|
/// Always contains `VersionDiff::NotInstalled`
|
||||||
|
GameNotInstalled(VersionDiff)
|
||||||
|
}
|
2
src/honkai/mod.rs
Normal file
2
src/honkai/mod.rs
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
#[cfg(feature = "states")]
|
||||||
|
pub mod states;
|
|
@ -1,47 +1,25 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use anime_game_core::prelude::*;
|
use serde::{Serialize, Deserialize};
|
||||||
use anime_game_core::genshin::prelude::*;
|
|
||||||
|
|
||||||
use wincompatlib::prelude::*;
|
use wincompatlib::prelude::*;
|
||||||
|
|
||||||
use serde::{Serialize, Deserialize};
|
use anime_game_core::prelude::*;
|
||||||
|
use anime_game_core::honkai::prelude::*;
|
||||||
|
|
||||||
use super::components::wine::WincompatlibWine;
|
use crate::components::wine::WincompatlibWine;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum LauncherState {
|
pub enum LauncherState {
|
||||||
Launch,
|
Launch,
|
||||||
|
|
||||||
/// Always contains `VersionDiff::Predownload`
|
/// Always contains `VersionDiff::Predownload`
|
||||||
PredownloadAvailable {
|
PredownloadAvailable(VersionDiff),
|
||||||
game: VersionDiff,
|
|
||||||
voices: Vec<VersionDiff>
|
|
||||||
},
|
|
||||||
|
|
||||||
FolderMigrationRequired {
|
|
||||||
from: PathBuf,
|
|
||||||
to: PathBuf,
|
|
||||||
cleanup_folder: Option<PathBuf>
|
|
||||||
},
|
|
||||||
|
|
||||||
UnityPlayerPatchAvailable(UnityPlayerPatch),
|
|
||||||
XluaPatchAvailable(XluaPatch),
|
|
||||||
|
|
||||||
#[cfg(feature = "components")]
|
#[cfg(feature = "components")]
|
||||||
WineNotInstalled,
|
WineNotInstalled,
|
||||||
|
|
||||||
PrefixNotExists,
|
PrefixNotExists,
|
||||||
|
|
||||||
// Always contains `VersionDiff::Diff`
|
|
||||||
VoiceUpdateAvailable(VersionDiff),
|
|
||||||
|
|
||||||
/// Always contains `VersionDiff::Outdated`
|
|
||||||
VoiceOutdated(VersionDiff),
|
|
||||||
|
|
||||||
/// Always contains `VersionDiff::NotInstalled`
|
|
||||||
VoiceNotInstalled(VersionDiff),
|
|
||||||
|
|
||||||
// Always contains `VersionDiff::Diff`
|
// Always contains `VersionDiff::Diff`
|
||||||
GameUpdateAvailable(VersionDiff),
|
GameUpdateAvailable(VersionDiff),
|
||||||
|
|
||||||
|
@ -52,16 +30,9 @@ pub enum LauncherState {
|
||||||
GameNotInstalled(VersionDiff)
|
GameNotInstalled(VersionDiff)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for LauncherState {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self::Launch
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub enum StateUpdating {
|
pub enum StateUpdating {
|
||||||
Game,
|
Game,
|
||||||
Voice(VoiceLocale),
|
|
||||||
Patch
|
Patch
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,11 +42,8 @@ pub struct LauncherStateParams<F: Fn(StateUpdating)> {
|
||||||
pub wine_prefix: PathBuf,
|
pub wine_prefix: PathBuf,
|
||||||
pub game_path: PathBuf,
|
pub game_path: PathBuf,
|
||||||
|
|
||||||
pub selected_voices: Vec<VoiceLocale>,
|
|
||||||
|
|
||||||
pub patch_servers: Vec<String>,
|
pub patch_servers: Vec<String>,
|
||||||
pub patch_folder: PathBuf,
|
pub patch_folder: PathBuf,
|
||||||
pub use_xlua_patch: bool,
|
|
||||||
|
|
||||||
pub status_updater: F
|
pub status_updater: F
|
||||||
}
|
}
|
||||||
|
@ -94,57 +62,12 @@ impl LauncherState {
|
||||||
|
|
||||||
let game = Game::new(¶ms.game_path);
|
let game = Game::new(¶ms.game_path);
|
||||||
|
|
||||||
// Check if game is installed
|
|
||||||
if game.is_installed() {
|
|
||||||
let data_folder = params.game_path.join(GameEdition::selected().data_folder());
|
|
||||||
|
|
||||||
let old_audio_folder_base = data_folder.join("StreamingAssets/Audio");
|
|
||||||
let old_audio_folder = old_audio_folder_base.join("GeneratedSoundBanks/Windows");
|
|
||||||
|
|
||||||
// Migrate pre-3.6 voiceovers format to post-3.6
|
|
||||||
if old_audio_folder.exists() {
|
|
||||||
return Ok(Self::FolderMigrationRequired {
|
|
||||||
from: old_audio_folder,
|
|
||||||
to: data_folder.join("StreamingAssets/AudioAssets"),
|
|
||||||
cleanup_folder: Some(old_audio_folder_base)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let diff = game.try_get_diff()?;
|
let diff = game.try_get_diff()?;
|
||||||
|
|
||||||
match diff {
|
match diff {
|
||||||
VersionDiff::Latest(_) | VersionDiff::Predownload { .. } => {
|
VersionDiff::Latest(_) | VersionDiff::Predownload { .. } => {
|
||||||
let mut predownload_voice = Vec::new();
|
|
||||||
|
|
||||||
for locale in params.selected_voices {
|
|
||||||
let mut voice_package = VoicePackage::with_locale(locale)?;
|
|
||||||
|
|
||||||
(params.status_updater)(StateUpdating::Voice(voice_package.locale()));
|
|
||||||
|
|
||||||
// Replace voice package struct with the one constructed in the game's folder
|
|
||||||
// so it'll properly calculate its difference instead of saying "not installed"
|
|
||||||
if voice_package.is_installed_in(¶ms.game_path) {
|
|
||||||
voice_package = match VoicePackage::new(get_voice_package_path(¶ms.game_path, voice_package.locale())) {
|
|
||||||
Some(locale) => locale,
|
|
||||||
None => return Err(anyhow::anyhow!("Failed to load {} voice package", voice_package.locale().to_name()))
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
let diff = voice_package.try_get_diff()?;
|
|
||||||
|
|
||||||
match diff {
|
|
||||||
VersionDiff::Latest(_) => (),
|
|
||||||
VersionDiff::Predownload { .. } => predownload_voice.push(diff),
|
|
||||||
|
|
||||||
VersionDiff::Diff { .. } => return Ok(Self::VoiceUpdateAvailable(diff)),
|
|
||||||
VersionDiff::Outdated { .. } => return Ok(Self::VoiceOutdated(diff)),
|
|
||||||
VersionDiff::NotInstalled { .. } => return Ok(Self::VoiceNotInstalled(diff))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check game patch status
|
// Check game patch status
|
||||||
(params.status_updater)(StateUpdating::Patch);
|
/*(params.status_updater)(StateUpdating::Patch);
|
||||||
|
|
||||||
let patch = Patch::new(¶ms.patch_folder);
|
let patch = Patch::new(¶ms.patch_folder);
|
||||||
|
|
||||||
|
@ -172,14 +95,11 @@ impl LauncherState {
|
||||||
if !xlua_patch.is_applied(¶ms.game_path)? {
|
if !xlua_patch.is_applied(¶ms.game_path)? {
|
||||||
return Ok(Self::XluaPatchAvailable(xlua_patch));
|
return Ok(Self::XluaPatchAvailable(xlua_patch));
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
// Check if update predownload available
|
// Check if update predownload available
|
||||||
if let VersionDiff::Predownload { .. } = diff {
|
if let VersionDiff::Predownload { .. } = diff {
|
||||||
Ok(Self::PredownloadAvailable {
|
Ok(Self::PredownloadAvailable(diff))
|
||||||
game: diff,
|
|
||||||
voices: predownload_voice
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Otherwise we can launch the game
|
// Otherwise we can launch the game
|
||||||
|
@ -231,24 +151,12 @@ impl LauncherState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut voices = Vec::with_capacity(config.game.voices.len());
|
|
||||||
|
|
||||||
for voice in config.game.voices {
|
|
||||||
voices.push(match VoiceLocale::from_str(&voice) {
|
|
||||||
Some(locale) => locale,
|
|
||||||
None => return Err(anyhow::anyhow!("Incorrect voice locale \"{}\" specified in the config", voice))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Self::get(LauncherStateParams {
|
Self::get(LauncherStateParams {
|
||||||
wine_prefix,
|
wine_prefix,
|
||||||
game_path: config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
game_path: config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||||
|
|
||||||
selected_voices: voices,
|
|
||||||
|
|
||||||
patch_servers: config.patch.servers,
|
patch_servers: config.patch.servers,
|
||||||
patch_folder: config.patch.path,
|
patch_folder: config.patch.path,
|
||||||
use_xlua_patch: config.patch.apply_xlua,
|
|
||||||
|
|
||||||
status_updater
|
status_updater
|
||||||
})
|
})
|
Loading…
Reference in a new issue