diff --git a/Cargo.lock b/Cargo.lock index b23f2ef..9cf78ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -200,6 +200,18 @@ version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "82cf52a69f51e16cffda2993f68b33a0fafd0d664163f87fa80e5e4fec2fc232" +[[package]] +name = "flate2" +version = "1.0.22" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f" +dependencies = [ + "cfg-if", + "crc32fast", + "libc", + "miniz_oxide", +] + [[package]] name = "fltk" version = "1.2.3" @@ -1091,6 +1103,7 @@ dependencies = [ "config", "failure", "fl2rust", + "flate2", "fltk", "nom 7.0.0", "nom_locate", diff --git a/Cargo.toml b/Cargo.toml index a7ee26a..07c3b27 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,6 +17,7 @@ failure = "^0.1.8" fltk = { version = "^1.2", features = ["fltk-bundled"], optional = true } nom = "^7.0.*" nom_locate = "^3.0.*" +flate2 = "^1.0.22" [build-dependencies] fl2rust = { version = "0.4", optional = true } diff --git a/src/egs/get_manifests.rs b/src/egs/get_manifests.rs index bb0f807..a659c64 100644 --- a/src/egs/get_manifests.rs +++ b/src/egs/get_manifests.rs @@ -27,7 +27,7 @@ pub enum EpicGamesManifestsError { ReadDirError { path: String, error: std::io::Error }, } -pub fn get_egs_manifests( +pub(crate) fn get_egs_manifests( settings: &EpicGamesLauncherSettings, ) -> Result, EpicGamesManifestsError> { use EpicGamesManifestsError::*; diff --git a/src/egs/manifest_item.rs b/src/egs/manifest_item.rs index 62cef95..4d5cb7a 100644 --- a/src/egs/manifest_item.rs +++ b/src/egs/manifest_item.rs @@ -2,7 +2,7 @@ use serde::{Deserialize, Serialize}; use steam_shortcuts_util::{Shortcut, shortcut::ShortcutOwned}; #[derive(Serialize, Deserialize, Debug, Clone)] -pub struct ManifestItem { +pub(crate) struct ManifestItem { #[serde(alias = "LaunchExecutable")] pub launch_executable: String, diff --git a/src/itch/butler_db_parser.rs b/src/itch/butler_db_parser.rs index 15f8e36..270192f 100644 --- a/src/itch/butler_db_parser.rs +++ b/src/itch/butler_db_parser.rs @@ -4,6 +4,7 @@ use nom::{ IResult, }; +#[derive(Debug, Clone, PartialEq, Eq, Hash)] pub(crate) struct DbPaths<'a> { pub(crate) base_path: &'a str, pub(crate) path: &'a str, diff --git a/src/itch/itch_platform.rs b/src/itch/itch_platform.rs index 01d0fa5..668dcac 100644 --- a/src/itch/itch_platform.rs +++ b/src/itch/itch_platform.rs @@ -1,7 +1,12 @@ use super::butler_db_parser::*; +use super::receipt::Receipt; use super::{ItchGame, ItchSettings}; use crate::platform::Platform; +use _core::iter::FromIterator; use failure::*; +use flate2::read::GzDecoder; +use std::collections::HashSet; +use std::io::prelude::*; use std::path::Path; pub struct ItchPlatform { @@ -36,7 +41,7 @@ impl Platform for ItchPlatform { let shortcut_bytes = std::fs::read(&itch_db_location).unwrap(); - let res = match parse_butler_db(&shortcut_bytes) { + let paths = match parse_butler_db(&shortcut_bytes) { Ok((_, shortcuts)) => Ok(shortcuts), Err(e) => Err(ItchErrors::ParseError { error: e.to_string(), @@ -44,18 +49,35 @@ impl Platform for ItchPlatform { }), }?; - let res = res - .iter() - .map(|paths| ItchGame { - install_path: paths.base_path.to_owned(), - executable: paths.path.to_owned(), - title: paths.path.to_owned(), - }) - .collect(); + //This is done to remove douplicates + let paths: HashSet<&DbPaths> = HashSet::from_iter(paths.iter()); + + let res = paths.iter().filter_map(|e| dbpath_to_game(*e)).collect(); Ok(res) } } +fn dbpath_to_game(paths: &DbPaths<'_>) -> Option { + let recipt = Path::new(paths.base_path) + .join(".itch") + .join("receipt.json.gz"); + if !&recipt.exists() { + return None; + } + + let gz_bytes = std::fs::read(&recipt).unwrap(); + let mut d = GzDecoder::new(gz_bytes.as_slice()); + let mut s = String::new(); + d.read_to_string(&mut s).unwrap(); + + let receipt_op: Option = serde_json::from_str(&s).ok(); + receipt_op.map(|re| ItchGame { + install_path: paths.base_path.to_owned(), + executable: paths.path.to_owned(), + title: re.game.title, + }) +} + #[cfg(target_os = "linux")] fn get_default_location() -> String { //If we don't have a home drive we have to just die diff --git a/src/itch/mod.rs b/src/itch/mod.rs index 2e2b7c1..fbcfe8c 100644 --- a/src/itch/mod.rs +++ b/src/itch/mod.rs @@ -2,6 +2,7 @@ mod settings; mod itch_game; mod itch_platform; mod butler_db_parser; +mod receipt; pub use settings::*; pub use itch_game::*; diff --git a/src/itch/receipt.rs b/src/itch/receipt.rs new file mode 100644 index 0000000..f9d1c71 --- /dev/null +++ b/src/itch/receipt.rs @@ -0,0 +1,11 @@ +use serde::{Deserialize, Serialize}; + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub(crate) struct Receipt{ + pub game:Game, +} + +#[derive(Serialize, Deserialize, Debug, Clone)] +pub(crate) struct Game{ + pub title:String +}