diff --git a/Cargo.lock b/Cargo.lock index bbc122c..cb70d17 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -6,6 +6,8 @@ version = "1.5.0" dependencies = [ "boxcars 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)", "dirs 2.0.2 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", + "serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -190,6 +192,11 @@ name = "if_chain" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "itoa" +version = "0.4.4" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "lazy_static" version = "1.4.0" @@ -414,6 +421,11 @@ name = "rustc-demangle" version = "0.1.16" source = "registry+https://github.com/rust-lang/crates.io-index" +[[package]] +name = "ryu" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" + [[package]] name = "serde" version = "1.0.101" @@ -432,6 +444,16 @@ dependencies = [ "syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "serde_json" +version = "1.0.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)", + "ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "siphasher" version = "0.2.3" @@ -522,6 +544,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3" "checksum fuchsia-cprng 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" "checksum if_chain 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c3360c7b59e5ffa2653671fb74b4741a5d343c03f331c0a4aeda42b5c2b0ec7d" +"checksum itoa 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "501266b7edd0174f8530248f87f99c88fbe60ca4ef3dd486835b8d8d53136f7f" "checksum lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" "checksum libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)" = "34fcd2c08d2f832f376f4173a231990fa5aef4e99fb569867318a227ef4c06ba" "checksum multimap 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de234f818d54830a7103b9be18ad0861d75aeb5e3c89759bc3f9a004cc39cfa3" @@ -549,8 +572,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum redox_users 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecedbca3bf205f8d8f5c2b44d83cd0690e39ee84b951ed649e9f1841132b66d" "checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf" "checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" +"checksum ryu 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c92464b447c0ee8c4fb3824ecc8383b81717b9f1e74ba2e72540aef7b9f82997" "checksum serde 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "9796c9b7ba2ffe7a9ce53c2287dfc48080f4b2b362fcc245a259b3a7201119dd" "checksum serde_derive 1.0.101 (registry+https://github.com/rust-lang/crates.io-index)" = "4b133a43a1ecd55d4086bd5b4dc6c1751c68b1bfbeba7a5040442022c7e7c02e" +"checksum serde_json 1.0.40 (registry+https://github.com/rust-lang/crates.io-index)" = "051c49229f282f7c6f3813f8286cc1e3323e8051823fce42c7ea80fe13521704" "checksum siphasher 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b8de496cf83d4ed58b6be86c3a275b8602f6ffe98d3024a869e124147a9a3ac" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" "checksum syn 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "66850e97125af79138385e9b88339cbcd037e3f28ceab8c5ad98e64f0f1f80bf" diff --git a/Cargo.toml b/Cargo.toml index 57f9dbe..8d03140 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,3 +9,5 @@ edition = "2018" [dependencies] boxcars = "0.5.0" dirs = "2.0.2" +serde = "1.0.101" +serde_json = "1.0.40" diff --git a/src/main.rs b/src/main.rs index 8db64d3..7e95c61 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,12 +1,30 @@ extern crate boxcars; extern crate dirs; +extern crate serde; + +use boxcars::{ParseError, Replay, HeaderProp}; +use serde_json; use std::env; +use std::error; use std::fs; -use std::io::{stdin}; +use std::io::{self, stdin, Read}; use std::path::*; use std::string::*; +#[derive(Default)] +struct PlayerStats { + name: String, + platform: String, + platform_id: String, + mvp: bool, + points: u32, + goals: u16, + assists: u16, + saves: u16, + shots: u16 +} + fn prompt_for_user_input(prompt: &str) -> String { println!("{}", prompt); let mut input = String::new(); @@ -27,11 +45,70 @@ fn read_path_input(prompt: &str) -> Result { Ok(full_path) } -fn run() -> Result<(), Box> { +fn parse_replay_data(data: &[u8]) -> Result { + boxcars::ParserBuilder::new(data) + .always_check_crc() + .never_parse_network_data() + .parse() +} + +fn parse_replay(path: &Path) -> Result> { + let mut file = fs::File::open(path)?; + let mut file_buffer = Vec::new(); + file.read_to_end(&mut file_buffer)?; + match parse_replay_data(&file_buffer) { + Ok(replay) => return Ok(replay), + Err(e) => return Err(Box::new(e)), + } +} + +fn get_player_stats_property(replay: Replay) -> Option { + for property in replay.properties { + if property.0 == "PlayerStats" { + return Some(property.1); + } + } + None +} + +fn make_player_stats(props: Vec<(String, HeaderProp)>) -> PlayerStats { + let player = PlayerStats::default(); + for prop in props { + let id = prop.0; + let val = prop.1; + match id.as_ref() { + "Name" => if let HeaderProp::Str(s) = val { player.name = s }, + "Platform" => if let HeaderProp::Str(s) = val { player.platform = s }, + "OnlineID" => if let HeaderProp::Str(s) = val { player.platform_id = s }, + } + } + player +} + +fn get_stats_from_player_stats(replay_stats: HeaderProp) -> Vec { + let stats = Vec::new(); + if let HeaderProp::Array(values) = replay_stats { + for player_info in values { + let player_stats = make_player_stats(values); + stats.push(player_stats); + } + } + stats +} + +fn run() -> Result<(), Box> { let args: Vec = env::args().collect(); println!("{:?}", args); let input_path: PathBuf = read_path_input("What is the path to the replay file directory")?; let output_path: PathBuf = read_path_input("What is the path to the output directory")?; + for entry in fs::read_dir(input_path)? { + let entry = entry?; + let file_path: PathBuf = entry.path(); + if file_path.is_dir() { continue; } + if !file_path.to_string_lossy().ends_with(".replay") { continue; } + let replay: Replay = parse_replay(&file_path)?; + println!("{}", file_path.to_string_lossy()); + } Ok(()) }