feat(core): initial multi-edition support
This commit is contained in:
parent
81e7b9c5a7
commit
6c442bd947
7 changed files with 57 additions and 34 deletions
|
@ -40,7 +40,7 @@ lazy_static::lazy_static! {
|
|||
/// This one is used to prepare some launcher UI components on start
|
||||
pub static ref CONFIG: Schema = Config::get().expect("Failed to load config");
|
||||
|
||||
pub static ref GAME: Game = Game::new(&CONFIG.game.path);
|
||||
pub static ref GAME: Game = Game::new(CONFIG.game.path.for_edition(CONFIG.launcher.edition));
|
||||
|
||||
/// Path to launcher folder. Standard is `$HOME/.local/share/anime-game-launcher`
|
||||
pub static ref LAUNCHER_FOLDER: PathBuf = launcher_dir().expect("Failed to get launcher folder");
|
||||
|
|
|
@ -21,7 +21,8 @@ pub struct DefaultPathsApp {
|
|||
runners: PathBuf,
|
||||
dxvks: PathBuf,
|
||||
prefix: PathBuf,
|
||||
game: PathBuf,
|
||||
game_global: PathBuf,
|
||||
game_china: PathBuf,
|
||||
components: PathBuf,
|
||||
patch: PathBuf,
|
||||
temp: PathBuf
|
||||
|
@ -33,7 +34,8 @@ pub enum Folders {
|
|||
Runners,
|
||||
DXVK,
|
||||
Prefix,
|
||||
Game,
|
||||
GameGlobal,
|
||||
GameChina,
|
||||
Components,
|
||||
Patch,
|
||||
Temp
|
||||
|
@ -147,14 +149,25 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
},
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: &tr("global-game-installation-folder"), // FIXME: locale
|
||||
set_title: &tr("global-game-installation-folder"),
|
||||
set_icon_name: Some("folder-symbolic"),
|
||||
set_activatable: true,
|
||||
|
||||
#[watch]
|
||||
set_subtitle: model.game.to_str().unwrap(),
|
||||
set_subtitle: model.game_global.to_str().unwrap(),
|
||||
|
||||
connect_activated => DefaultPathsAppMsg::ChoosePath(Folders::Game)
|
||||
connect_activated => DefaultPathsAppMsg::ChoosePath(Folders::GameGlobal)
|
||||
},
|
||||
|
||||
adw::ActionRow {
|
||||
set_title: &tr("chinese-game-installation-folder"),
|
||||
set_icon_name: Some("folder-symbolic"),
|
||||
set_activatable: true,
|
||||
|
||||
#[watch]
|
||||
set_subtitle: model.game_china.to_str().unwrap(),
|
||||
|
||||
connect_activated => DefaultPathsAppMsg::ChoosePath(Folders::GameChina)
|
||||
},
|
||||
|
||||
adw::ActionRow {
|
||||
|
@ -272,7 +285,8 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
runners: CONFIG.game.wine.builds.clone(),
|
||||
dxvks: CONFIG.game.dxvk.builds.clone(),
|
||||
prefix: CONFIG.game.wine.prefix.clone(),
|
||||
game: CONFIG.game.path.clone(),
|
||||
game_global: CONFIG.game.path.global.clone(),
|
||||
game_china: CONFIG.game.path.china.clone(),
|
||||
components: CONFIG.components.path.clone(),
|
||||
patch: CONFIG.patch.path.clone(),
|
||||
|
||||
|
@ -302,24 +316,26 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
|
||||
match folder {
|
||||
Folders::Launcher => {
|
||||
self.runners = result.join("runners");
|
||||
self.dxvks = result.join("dxvks");
|
||||
self.prefix = result.join("prefix");
|
||||
self.game = result.join(concat!("Hon", "kai Sta", "r Rail"));
|
||||
self.components = result.join("components");
|
||||
self.patch = result.join("patch");
|
||||
self.temp = result.clone();
|
||||
self.runners = result.join("runners");
|
||||
self.dxvks = result.join("dxvks");
|
||||
self.prefix = result.join("prefix");
|
||||
self.game_global = result.join("HSR");
|
||||
self.game_china = result.join("HSR China"); // TODO change this
|
||||
self.components = result.join("components");
|
||||
self.patch = result.join("patch");
|
||||
self.temp = result.clone();
|
||||
|
||||
self.launcher = result;
|
||||
}
|
||||
|
||||
Folders::Runners => self.runners = result,
|
||||
Folders::DXVK => self.dxvks = result,
|
||||
Folders::Prefix => self.prefix = result,
|
||||
Folders::Game => self.game = result,
|
||||
Folders::Components => self.components = result,
|
||||
Folders::Patch => self.patch = result,
|
||||
Folders::Temp => self.temp = result
|
||||
Folders::Runners => self.runners = result,
|
||||
Folders::DXVK => self.dxvks = result,
|
||||
Folders::Prefix => self.prefix = result,
|
||||
Folders::GameGlobal => self.game_global = result,
|
||||
Folders::GameChina => self.game_china = result,
|
||||
Folders::Components => self.components = result,
|
||||
Folders::Patch => self.patch = result,
|
||||
Folders::Temp => self.temp = result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -339,7 +355,8 @@ impl SimpleAsyncComponent for DefaultPathsApp {
|
|||
(old_config.game.wine.builds, &self.runners),
|
||||
(old_config.game.dxvk.builds, &self.dxvks),
|
||||
(old_config.game.wine.prefix, &self.prefix),
|
||||
(old_config.game.path, &self.game),
|
||||
(old_config.game.path.global, &self.game_global),
|
||||
(old_config.game.path.china, &self.game_china),
|
||||
(old_config.components.path, &self.components),
|
||||
(old_config.patch.path, &self.patch)
|
||||
];
|
||||
|
@ -399,7 +416,8 @@ impl DefaultPathsApp {
|
|||
config.game.wine.builds = self.runners.clone();
|
||||
config.game.dxvk.builds = self.dxvks.clone();
|
||||
config.game.wine.prefix = self.prefix.clone();
|
||||
config.game.path = self.game.clone();
|
||||
config.game.path.global = self.game_global.clone();
|
||||
config.game.path.china = self.game_china.clone();
|
||||
config.components.path = self.components.clone();
|
||||
config.patch.path = self.patch.clone();
|
||||
config.launcher.temp = Some(self.temp.clone());
|
||||
|
|
|
@ -18,7 +18,9 @@ pub fn apply_patch(sender: ComponentSender<App>, patch: MainPatch) {
|
|||
std::thread::spawn(move || {
|
||||
let mut apply_patch_if_needed = true;
|
||||
|
||||
if let Err(err) = patch.apply(config.game.path, config.patch.root) {
|
||||
let game_path = config.game.path.for_edition(config.launcher.edition);
|
||||
|
||||
if let Err(err) = patch.apply(game_path, config.patch.root) {
|
||||
tracing::error!("Failed to patch the game");
|
||||
|
||||
sender.input(AppMsg::Toast {
|
||||
|
|
|
@ -17,8 +17,9 @@ pub fn download_diff(sender: ComponentSender<App>, progress_bar_input: Sender<Pr
|
|||
|
||||
std::thread::spawn(move || {
|
||||
let config = Config::get().unwrap();
|
||||
let game_path = config.game.path.for_edition(config.launcher.edition).to_path_buf();
|
||||
|
||||
let result = diff.install_to_by(config.game.path, config.launcher.temp, clone!(@strong sender => move |state| {
|
||||
let result = diff.install_to_by(game_path, config.launcher.temp, clone!(@strong sender => move |state| {
|
||||
match &state {
|
||||
DiffUpdate::InstallerUpdate(InstallerUpdate::DownloadingError(err)) => {
|
||||
tracing::error!("Downloading failed: {err}");
|
||||
|
|
|
@ -530,8 +530,8 @@ impl SimpleComponent for App {
|
|||
|
||||
group.add_action::<GameFolder>(&RelmAction::new_stateless(clone!(@strong sender => move |_| {
|
||||
let path = match Config::get() {
|
||||
Ok(config) => config.game.path,
|
||||
Err(_) => CONFIG.game.path.clone()
|
||||
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf()
|
||||
};
|
||||
|
||||
if let Err(err) = open::that(path) {
|
||||
|
|
|
@ -22,6 +22,8 @@ pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<Prog
|
|||
std::thread::spawn(move || {
|
||||
match repairer::try_get_integrity_files(None) {
|
||||
Ok(files) => {
|
||||
let game_path = config.game.path.for_edition(config.launcher.edition).to_path_buf();
|
||||
|
||||
progress_bar_input.send(ProgressBarMsg::UpdateProgress(0, 0));
|
||||
|
||||
let mut total = 0;
|
||||
|
@ -52,7 +54,7 @@ pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<Prog
|
|||
|
||||
let thread_sender = verify_sender.clone();
|
||||
|
||||
std::thread::spawn(clone!(@strong config.game.path as game_path => move || {
|
||||
std::thread::spawn(clone!(@strong game_path => move || {
|
||||
for file in thread_files {
|
||||
let status = if config.launcher.repairer.fast {
|
||||
file.fast_verify(&game_path)
|
||||
|
@ -94,7 +96,7 @@ pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<Prog
|
|||
let total = broken.len() as f64;
|
||||
|
||||
let main_patch = MainPatch::from_folder(&config.patch.path).unwrap()
|
||||
.is_applied(&config.game.path).unwrap();
|
||||
.is_applied(&game_path).unwrap();
|
||||
|
||||
tracing::debug!("Patch status: {main_patch}");
|
||||
|
||||
|
@ -115,7 +117,7 @@ pub fn repair_game(sender: ComponentSender<App>, progress_bar_input: Sender<Prog
|
|||
if !should_ignore(&file.path, main_patch) {
|
||||
tracing::debug!("Repairing file: {}", file.path.to_string_lossy());
|
||||
|
||||
if let Err(err) = file.repair(&config.game.path) {
|
||||
if let Err(err) = file.repair(&game_path) {
|
||||
sender.input(AppMsg::Toast {
|
||||
title: tr("game-file-repairing-error"),
|
||||
description: Some(err.to_string())
|
||||
|
|
|
@ -311,8 +311,8 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
|
||||
PatchStatus::Available { .. } => unsafe {
|
||||
let path = match Config::get() {
|
||||
Ok(config) => config.game.path,
|
||||
Err(_) => CONFIG.game.path.clone(),
|
||||
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(),
|
||||
};
|
||||
|
||||
if let Ok(true) = model.main_patch.as_ref().unwrap_unchecked().is_applied(path) {
|
||||
|
@ -337,8 +337,8 @@ impl SimpleAsyncComponent for GeneralApp {
|
|||
PatchStatus::Testing { .. } => tr("patch-testing-tooltip"),
|
||||
PatchStatus::Available { .. } => unsafe {
|
||||
let path = match Config::get() {
|
||||
Ok(config) => config.game.path,
|
||||
Err(_) => CONFIG.game.path.clone(),
|
||||
Ok(config) => config.game.path.for_edition(config.launcher.edition).to_path_buf(),
|
||||
Err(_) => CONFIG.game.path.for_edition(CONFIG.launcher.edition).to_path_buf(),
|
||||
};
|
||||
|
||||
if let Ok(true) = model.main_patch.as_ref().unwrap_unchecked().is_applied(path) {
|
||||
|
|
Loading…
Reference in a new issue