Skip to content

Commit

Permalink
Adds auto-conflict for non-RTC mister files & finds the rom files for…
Browse files Browse the repository at this point in the history
… MiSTer only games (seems fast enough without a cache)
  • Loading branch information
neil-morrison44 committed Nov 3, 2022
1 parent c631883 commit ef1f74f
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 14 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "pocket-sync"
version = "0.1.0"
version = "0.2.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
Expand Down
23 changes: 23 additions & 0 deletions src/cores.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ pub trait TransformCore {
fn from_mister(name: &str) -> Option<SupportedCore>;

fn pocket_folder(&self) -> String;

fn rom_filetypes(&self) -> Vec<String>;
}

impl TransformCore for SupportedCore {
Expand Down Expand Up @@ -101,6 +103,27 @@ impl TransformCore for SupportedCore {
_ => "common",
})
}

fn rom_filetypes(&self) -> Vec<String> {
(match self {
SupportedCore::Arduboy => vec!["hex"],
SupportedCore::GameGear => vec!["gg"],
SupportedCore::GB => vec!["gb"],
SupportedCore::GBA => vec!["gba"],
SupportedCore::GBC => vec!["gbc"],
SupportedCore::Genesis => vec!["md", "bin", "gen", "smd"],
SupportedCore::MasterSystem => vec!["sms"],
SupportedCore::NEOGEO => vec!["json"],
SupportedCore::NES => vec!["nes"],
SupportedCore::SNES => vec!["smc", "sfc"],
SupportedCore::SuperVision => vec!["sv", "bin"],
SupportedCore::TGFX16 => vec!["pce"],
_ => vec![],
})
.iter()
.map(|s| s.to_string())
.collect()
}
}

#[cfg(test)]
Expand Down
1 change: 1 addition & 0 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod config_file;
mod cores;
mod mister_ftp;
mod pocket_files;
mod save_compare;
mod user_input;

Expand Down
56 changes: 56 additions & 0 deletions src/pocket_files.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
use std::{
ffi::OsStr,
path::{Component, PathBuf},
};
use walkdir::WalkDir;

pub fn find_roms_for_save(
save_name: &str,
file_types: &Vec<String>,
pocket_path: &PathBuf,
) -> Vec<PathBuf> {
let mut found_paths = vec![];
let assets_path = pocket_path.join("Assets");

let potential_rom_names: Vec<String> = file_types
.iter()
.map(|f| save_name.replace(".sav", format!(".{}", f.as_str()).as_str()))
.collect();

for entry in WalkDir::new(assets_path).into_iter().filter_map(|e| e.ok()) {
if !entry.file_type().is_file() {
continue;
}

if let Some(file_name) = entry
.file_name()
.to_str()
.and_then(|s| Some(String::from(s)))
{
if potential_rom_names.contains(&file_name) {
found_paths.push(entry.path().to_path_buf());
}
}
}

found_paths
}

pub fn convert_rom_path_to_save_path(rom_path: &PathBuf) -> PathBuf {
let file_name = format!("{}.sav", rom_path.file_stem().unwrap().to_str().unwrap());

let mut save_path: PathBuf = PathBuf::new();
let components = rom_path.components();
for component in components {
if component.as_os_str().to_string_lossy() == String::from("Assets") {
save_path = save_path.join("Saves");
} else {
save_path = save_path.join(component);
}
}

save_path.pop();
save_path = save_path.join(file_name);

save_path
}
57 changes: 44 additions & 13 deletions src/save_compare.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use crate::{cores::TransformCore, PlatformSave, SaveInfo};
use crate::{
cores::TransformCore,
pocket_files::{convert_rom_path_to_save_path, find_roms_for_save},
PlatformSave, SaveInfo,
};
use std::{
fmt,
fs::File,
Expand Down Expand Up @@ -83,30 +87,49 @@ impl SaveComparison<'_> {
let file_name = path.file_name().unwrap();
let mut save_file = ftp_stream.retr_as_buffer(file_name.to_str().unwrap())?;

let pocket_save_path = match self {
SaveComparison::MiSTerOnly(save_info) => pocket_path.join(format!(
"Saves/{}/{}/{}",
save_info.core.to_pocket(),
save_info.core.pocket_folder(),
save_info.game
)),
let pocket_save_paths: Vec<PathBuf> = match self {
SaveComparison::MiSTerOnly(save_info) => {
let found = find_roms_for_save(
&save_info.game,
&save_info.core.rom_filetypes(),
&pocket_path,
)
.iter()
.map(|p| convert_rom_path_to_save_path(p))
.collect();

found
}
Self::PocketNewer(save_pair)
| Self::MiSTerNewer(save_pair)
| Self::Conflict(save_pair) => pocket_path.join(save_pair.pocket.path.clone()),
| Self::Conflict(save_pair) => vec![pocket_path.join(save_pair.pocket.path.clone())],
Self::PocketOnly(_) => panic!("Attempt to use a non-existent MiSTer save"),
Self::NoSyncNeeded => panic!("Attempt to sync when NoSyncNeeded"),
};

if pocket_save_paths.len() == 0 {
println!(
"Couldn't find \"{}\" on the pocket, skipping",
mister_save_info.game.replace(".sav", "")
);
return Ok(());
}

println!(
"Copying {} ({}) \nMiSTer -> Pocket",
mister_save_info.game,
mister_save_info.core.to_pocket()
);

let mut file = File::create(pocket_save_path).unwrap();
let mut buf: Vec<u8> = Vec::new();
save_file.read_to_end(&mut buf).unwrap();
file.write(&buf).unwrap();
for pocket_save_path in pocket_save_paths {
let prefix = pocket_save_path.parent().unwrap();
std::fs::create_dir_all(prefix).unwrap();

let mut file = File::create(pocket_save_path).unwrap();
let mut buf: Vec<u8> = Vec::new();
save_file.read_to_end(&mut buf).unwrap();
file.write(&buf).unwrap();
}

return Ok(());
}
Expand Down Expand Up @@ -195,6 +218,14 @@ fn get_comparison<'a>(
mister_save_info: &'a SaveInfo,
last_merge: i64,
) -> SaveComparison<'a> {
if mister_save_info.date_modified < 86400 {
// MiSTer save was updated while the RTC wasn't running - raise as a conflict to be safe
return SaveComparison::Conflict(SavePair {
pocket: pocket_save_info,
mister: mister_save_info,
});
}

if pocket_save_info.date_modified < last_merge && mister_save_info.date_modified < last_merge {
return SaveComparison::NoSyncNeeded;
}
Expand Down

0 comments on commit ef1f74f

Please sign in to comment.