extern crate indexmap; extern crate lazy_static; extern crate log; extern crate regex; extern crate reqwest; extern crate select; extern crate serde; extern crate serde_json; extern crate simple_logger; extern crate winreg; use indexmap::IndexMap; use serde_json::Value; use std::fs; use std::path::PathBuf; #[derive(Serialize, Deserialize)] struct ItemSet { title: String, #[serde(rename = "type")] type_: String, map: String, mode: String, priority: bool, sortrank: u32, blocks: Vec, } const CONSUMABLES: [u32; 9] = [2003, 2004, 2055, 2031, 2032, 2033, 2138, 2140, 2139]; const TRINKETS: [u32; 3] = [3340, 3364, 3363]; const ITEM_TYPES: &'static [(&str, [&str; 2]); 4] = &[ ("Most Frequent Starters", ["firstItems", "mostGames"]), ( "Highest Win % Starters", ["firstItems", "highestWinPercent"], ), ("Most Frequent Core Build", ["items", "mostGames"]), ("Highest Win % Core Build", ["items", "highestWinPercent"]), ]; pub trait DataSource { fn get_champs_with_positions_and_patch( client: &reqwest::Client, ) -> (IndexMap>, String); fn get_champ_data(id: &str, position: &str, client: &reqwest::Client) -> Option; fn make_item_set(data: &Value, label: &str) -> Value { json!({ "items": data["items"].as_array().unwrap().iter().map(|x| json!({"id": x["id"].as_str(), "count": 1})).collect::>(), "type": format!("{} ({:.2}% - {} games)", label, data["winPercent"].as_f64().unwrap() * 100., data["games"].as_u64().unwrap()) }) } fn make_item_set_from_list(list: &Vec, label: &str, key: &str, data: &Value) -> Value { let mut key_order = String::new(); if !data["skills"].get("skillInfo").is_none() { key_order = data["skills"][key]["order"] .as_array() .unwrap() .iter() .map(|x| { data["skills"]["skillInfo"].as_array().unwrap() [x.as_str().unwrap().parse::().unwrap() - 1]["key"] .as_str() .unwrap() }) .collect::>() .join("."); } json!({ "items": list.iter().map(|x| json!({"id": x.to_string(), "count": 1})).collect::>(), "type": format!("{} {}", label, key_order) }) } fn write_item_set( id: &str, name: &str, pos: &str, ver: &str, path: &PathBuf, client: &reqwest::Client, ) { info!("Retrieving data for {} at {}", name, pos); let data = Self::get_champ_data(id, pos, client); match data { Some(data) => { let mut item_set = ItemSet { title: format!( "CGG {} {} - {:.2}%", pos, ver, data["stats"]["winRate"].as_f64().unwrap() * 100. ), type_: "custom".to_string(), map: "any".to_string(), mode: "any".to_string(), priority: false, sortrank: 0, blocks: vec![], }; for (label, path) in ITEM_TYPES.iter() { if !data[&path[0]].get(&path[1]).is_none() { item_set .blocks .push(Self::make_item_set(&data[&path[0]][&path[1]], label)); } } item_set.blocks.push(Self::make_item_set_from_list( &CONSUMABLES.to_vec(), "Consumables | Frequent:", "mostGames", &data, )); item_set.blocks.push(Self::make_item_set_from_list( &TRINKETS.to_vec(), "Trinkets | Wins:", "highestWinPercent", &data, )); info!("Writing item set for {} at {}", name, pos); fs::write( path.join(format!("CGG_{}_{}.json", id, pos)), serde_json::to_string_pretty(&item_set).unwrap(), ).unwrap(); } None => { error!("Can't get data for {} at {}", id, pos); } } } }