Skip to content

Commit

Permalink
Improved game name handling, fix if name was not found
Browse files Browse the repository at this point in the history
. game names like "Dungeon of the ENDLESS™ - Definitive Edition" did not work
  with zenity (silent crashes) so game name is no longer used in UI dialogs
. fix: unsafe usage of `unwrap()` caused crashes if no backup to restore was
  found
. backup logic now uses WrapGameInfo to determine whether we can back this game
  up or not
  • Loading branch information
sluedecke committed Nov 12, 2023
1 parent 7d25987 commit 9a205ce
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 16 deletions.
44 changes: 28 additions & 16 deletions src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -816,20 +816,23 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
// Because heroic calls us with env XDG_CONFIG_HOME=/home/saschal/.config/heroic/legendaryConfig
// so we use an empty, default config.
// WORKAROUND: call ludusavi with --config
log::debug!("WRAP::restore: config is {:#?}", config);
log::debug!("WRAP::restore: config has these roots: {:#?}", config.roots);
let title_finder = TitleFinder::new(
&manifest,
&BackupLayout::new(config.restore.path.clone(), config.backup.retention.clone()),
);

let mut game_name: Option<String> = None;
log::debug!("WRAP::restore: title_finder input: {:?}", wrap_game_info);
if wrap_game_info.name.is_some() {
game_name =
title_finder.find_one(&[wrap_game_info.name.clone().unwrap()], &None, &None, true, false, true);
}
log::debug!("WRAP::restore: title_finder first output: {:?}", game_name);
if game_name.is_none() && wrap_game_info.gog_id.is_some() {
game_name = title_finder.find_one(&[], &None, &wrap_game_info.gog_id, false, false, true);
}
log::debug!("WRAP::restore: title_finder second output: {:?}", game_name);
match game_name {
Some(ref name) => {
log::debug!("WRAP::restore: title_finder returns: {}", name);
Expand All @@ -841,7 +844,8 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
);
match crate::wrap::ui::confirm_with_question(
gui,
&format!("Could not find a restorable backup for {:?}.", wrap_game_info),
// &format!("Could not find a restorable backup for {}.", wrap_game_info),
"Could not find a restorable backup.",
"Continue to launch game anyways?",
) {
Ok(confirmation) => match confirmation {
Expand All @@ -858,14 +862,13 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
};
}
};
let mut game_name = game_name.unwrap();

//
// restore
//
// TODO.2023-07-12 detect if there are differences between backed up and actual saves
if !skip_restore {
match crate::wrap::ui::confirm_continue(gui, &format!("About to restore backup for {}.", game_name)) {
match crate::wrap::ui::confirm_continue(gui, "Continue with backup restoration?") {
Ok(confirmation) => match confirmation {
true => {}
false => {
Expand All @@ -880,7 +883,7 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
};
if let Err(err) = run(
Subcommand::Restore {
games: vec![game_name.clone()],
games: vec![game_name.unwrap().clone()],
force: true,
// everything else is default
// force: Default::default(),
Expand All @@ -895,14 +898,16 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
no_manifest_update,
try_manifest_update,
) {
log::error!("WRAP::restore: failed for game {} with: {:?}", game_name, err);
log::error!("WRAP::restore: failed for game {:?} with: {:?}", wrap_game_info, err);
let _ = crate::wrap::ui::alert_with_error(
gui,
"Savegame restoration failed, aborting.",
&format!("{:?}", err),
);
break 'wrap;
}
} else {
log::debug!("WRAP::restore: skipping game restore");
}

//
Expand Down Expand Up @@ -931,19 +936,26 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
// Check if ludusavi is able to back up
//
// TODO.2023-11-11 adjust to WrapGameInfo
match title_finder.find_one(&[game_name.clone()], &None, &None, true, true, false) {
Some(name) => {
let mut game_name: Option<String> = None;
log::debug!("WRAP::backup: title_finder input: {:?}", wrap_game_info);
if wrap_game_info.name.is_some() {
game_name =
title_finder.find_one(&[wrap_game_info.name.clone().unwrap()], &None, &None, true, true, false);
}
log::debug!("WRAP::backup: title_finder first output: {:?}", game_name);
if game_name.is_none() && wrap_game_info.gog_id.is_some() {
game_name = title_finder.find_one(&[], &None, &wrap_game_info.gog_id, false, true, false);
}
log::debug!("WRAP::backup: title_finder second output: {:?}", game_name);
match game_name {
Some(ref name) => {
log::debug!("WRAP::backup: title_finder returns: {}", name);
game_name = name;
}
None => {
log::error!("WRAP::backup: title_finder returned nothing for {}", game_name);
log::error!("WRAP::backup: title_finder returned nothing for {:?}", wrap_game_info);
let _ = crate::wrap::ui::alert(
gui,
&format!(
"Game ran, but ludusavi does not know how to back up {}. Aborting.",
game_name
),
"Game ran, but ludusavi does not know how to back up this game. Aborting.",
);
break 'wrap;
}
Expand All @@ -952,7 +964,7 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
//
// backup
//
match crate::wrap::ui::confirm_simple(gui, &format!("About to backup savegames for {}", game_name)) {
match crate::wrap::ui::confirm_simple(gui, "Continue with savegame backup?") {
Ok(confirmation) => match confirmation {
true => {}
false => {
Expand All @@ -967,7 +979,7 @@ pub fn run(sub: Subcommand, no_manifest_update: bool, try_manifest_update: bool)
};
if let Err(err) = run(
Subcommand::Backup {
games: vec![game_name],
games: vec![game_name.unwrap().clone()],
force: true,
// everything else is default
// force: Default::default(),
Expand Down
19 changes: 19 additions & 0 deletions src/wrap.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
use std::fmt::Display;

use crate::{prelude::Error, resource::config::RootsConfig};

mod gogdl;
Expand All @@ -12,6 +14,23 @@ pub struct WrapGameInfo {
pub gog_id: Option<u64>,
}

impl Display for WrapGameInfo {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let mut result: String = "".to_string();

if self.name.is_some() {
result += self.name.as_ref().unwrap().as_str();
}
if self.gog_id.is_some() {
if !result.is_empty() {
result += ", ";
}
result += &format!("GOG Id: {}", self.name.as_ref().unwrap().as_str());
}
write!(f, "{}", result)
}
}

impl WrapGameInfo {
fn is_empty(&self) -> bool {
self.name.is_none() && self.gog_id.is_none()
Expand Down

0 comments on commit 9a205ce

Please sign in to comment.