diff --git a/Cargo.lock b/Cargo.lock index 67af1b7..6281efd 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,5 +1,7 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + [[package]] name = "arrayref" version = "0.3.6" @@ -12,6 +14,17 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -24,6 +37,12 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd" +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + [[package]] name = "blake2b_simd" version = "0.5.11" @@ -41,6 +60,38 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "clap" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd1061998a501ee7d4b6d449020df3266ca3124b941ec56cf2005c3779ca142" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", + "unicode-width", + "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.0.0-beta.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "370f715b81112975b1b69db93e0b56ea4cd4e5002ac43b2da8474106a54096a1" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "constant_time_eq" version = "0.1.5" @@ -106,6 +157,40 @@ dependencies = [ "wasi 0.10.2+wasi-snapshot-preview1", ] +[[package]] +name = "hashbrown" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e" + +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + +[[package]] +name = "hermit-abi" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33" +dependencies = [ + "libc", +] + +[[package]] +name = "indexmap" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5" +dependencies = [ + "autocfg", + "hashbrown", +] + [[package]] name = "lazy_static" version = "1.4.0" @@ -118,12 +203,60 @@ version = "0.2.93" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9385f66bf6105b241aa65a61cb923ef20efc665cb9f9bb50ac2f0c4b7f378d41" +[[package]] +name = "os_str_bytes" +version = "2.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afb2e1c3ee07430c2cf76151675e583e0f19985fa6efae47d6848a3e2c824f85" + [[package]] name = "ppv-lite86" version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac74c624d6b2d21f425f752262f42188365d7b8ff1aff74c82e45136510a4857" +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.28" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c7ed8b8c7b886ea3ed7dde405212185f423ab44682667c8c6dd14aa1d9f6612" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3d0b9745dc2debf507c8422de05d7226cc1f0644216dfdfead988f9b1ab32a7" +dependencies = [ + "proc-macro2", +] + [[package]] name = "rand" version = "0.8.3" @@ -195,13 +328,79 @@ dependencies = [ [[package]] name = "steam_randomiser" -version = "0.1.1" +version = "0.2.0" dependencies = [ + "clap", "dirs", "rand", "which", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + +[[package]] +name = "syn" +version = "1.0.74" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1873d832550d4588c3dbc20f01361ab00bfe741048f71e3fecf145a7cc18b29c" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "203008d98caf094106cfaba70acfed15e18ed3ddb7d94e49baec153a2b462789" +dependencies = [ + "unicode-width", +] + +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + +[[package]] +name = "unicode-xid" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" + +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + +[[package]] +name = "version_check" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe" + [[package]] name = "wasi" version = "0.9.0+wasi-snapshot-preview1" @@ -240,6 +439,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" diff --git a/Cargo.toml b/Cargo.toml index 66d0e83..28855f6 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "steam_randomiser" -version = "0.1.1" +version = "0.2.0" authors = ["Dimitri Belopopsky "] edition = "2018" license = "MIT" @@ -18,6 +18,7 @@ categories = ["command-line-utilities"] dirs = "3.0.1" rand = "0.8.3" which = "4.1.0" +clap = "3.0.0-beta.2" [profile.release] lto = true diff --git a/src/main.rs b/src/main.rs index 2a867b6..64a1677 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,11 +1,19 @@ -use std::{fs::DirEntry, path::{Path, PathBuf}, process::{Child, Command, Stdio}}; - +use clap::{AppSettings, Clap}; use rand::seq::SliceRandom; +use std::{ + fs::DirEntry, + path::{Path, PathBuf}, + process::{Child, Command, Stdio}, +}; const FLATPAK_APPLICATIONS_PATH: &str = ".var/app/com.valvesoftware.Steam/data/Steam"; -const VANILLA_APPLICATIONS_PATH_NIX: &str = r#".local/share/Steam"#; +#[cfg(target_os = "linux")] +const VANILLA_APPLICATIONS_PATH: &str = r#".local/share/Steam"#; #[cfg(target_os = "windows")] -const VANILLA_APPLICATIONS_PATH_WINDOWS: &str = r#"C:\Program Files (x86)\Steam"#; +const VANILLA_APPLICATIONS_PATH: &str = r#"C:\Program Files (x86)\Steam"#; +#[cfg(target_os = "macos")] +const VANILLA_APPLICATIONS_PATH: &str = r#"Library/Application Support/Steam"#; + const MANIFEST_DIR: &str = "steamapps/"; @@ -26,6 +34,7 @@ fn is_proton(app_name: &str) -> bool { false } +/// List of names of applications/games we don't want to launch. fn is_blacklisted(app_name: &str) -> bool { let steam_libs = [ "Steamworks Common Redistributables", @@ -39,6 +48,7 @@ fn is_blacklisted(app_name: &str) -> bool { || app_name.starts_with("Steam Linux Runtime") } +/// Find other install directories which are not the default one fn get_other_install_dirs(path: &Path) -> Vec { let mut path = path.to_path_buf(); path.push("libraryfolders.vdf"); @@ -52,9 +62,9 @@ fn get_other_install_dirs(path: &Path) -> Vec { let lines = lines.lines().skip(2).collect::>(); for line in lines.iter().take(lines.len() - 1) { let path = line - .split('\t') - .filter(|s| !s.is_empty()) - .collect::>(); + .split('\t') + .filter(|s| !s.is_empty()) + .collect::>(); let tag = path[0].replace("\"", ""); let path = path[1].trim().replace("\"", ""); @@ -149,7 +159,16 @@ fn detect_steam() -> SteamKind { #[cfg(target_os = "windows")] fn detect_steam() -> SteamKind { let has_steam_vanilla = which::which(r#"C:\Program Files (x86)\Steam\steam.exe"#).is_ok(); - match (has_steam_vanilla) { + match has_steam_vanilla { + true => SteamKind::Vanilla, + _ => SteamKind::NotFound, + } +} + +#[cfg(target_os = "macos")] +fn detect_steam() -> SteamKind { + let has_steam_vanilla = which::which("steam").is_ok(); + match has_steam_vanilla { true => SteamKind::Vanilla, _ => SteamKind::NotFound, } @@ -157,7 +176,7 @@ fn detect_steam() -> SteamKind { #[cfg(target_os = "linux")] fn run(steam_type: SteamKind, id: &str) -> std::io::Result { - let child = match steam_type { + let child = match steam_type { SteamKind::Flatpak => std::process::Command::new("flatpak") .args(&[ "run", @@ -185,18 +204,48 @@ fn run(steam_type: SteamKind, id: &str) -> std::io::Result { .arg(&generate_steam_rungame(id)) .stdout(Stdio::null()) .stderr(Stdio::null()) - .spawn() + .spawn()? } _ => panic!("Couldn't find steam!"), }; - Some(child) + Ok(child) +} + +#[cfg(target_os = "macos")] +fn run(steam_type: SteamKind, id: &str) -> std::io::Result { + let child = match steam_type { + SteamKind::Vanilla => std::process::Command::new("steam") + .arg(&generate_steam_rungame(id)) + .stdout(Stdio::null()) + .stderr(Stdio::null()) + .spawn()?, + SteamKind::NotFound => panic!("Couldn't find steam!"), + }; + Ok(child) +} + +/// Randomly picks an installed game from your Steam library and launches it. +#[derive(Clap)] +#[clap( + version = "0.2.0" +)] +#[clap(setting = AppSettings::ColoredHelp)] +struct Opts { + /// Show short message telling which game is being launched + #[clap(short, long, parse(from_occurrences))] + verbose: i32, + /// Runs the program but doesn't launch the game. + #[clap(short, long)] + dry_run: bool } fn main() { + let opts: Opts = Opts::parse(); + let steam_type = detect_steam(); if steam_type == SteamKind::NotFound { - eprintln!("Couldn't find Steam."); + eprintln!("Couldn't find Steam. Please make sure it is installed."); return; } @@ -204,10 +253,7 @@ fn main() { let mut home = dirs::home_dir().unwrap(); match steam_type { SteamKind::Flatpak => home.push(FLATPAK_APPLICATIONS_PATH), - #[cfg(target_os = "linux")] - SteamKind::Vanilla => home.push(VANILLA_APPLICATIONS_PATH_NIX), - #[cfg(target_os = "windows")] - SteamKind::Vanilla => home.push(VANILLA_APPLICATIONS_PATH_WINDOWS), + SteamKind::Vanilla => home.push(VANILLA_APPLICATIONS_PATH), _ => {} } home @@ -228,7 +274,11 @@ fn main() { let (game, id) = games.choose(&mut rand::thread_rng()).unwrap(); - println!("Randomly launching \"{}\"! Have fun!", game); - - let _ = run(steam_type, id).unwrap(); -} \ No newline at end of file + if opts.verbose > 0 { + println!("Randomly launching \"{}\"! Have fun!", game); + } + + if !opts.dry_run { + let _ = run(steam_type, id).unwrap(); + } +}