2018-06-16 10:48:46 +02:00
|
|
|
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<Value>,
|
|
|
|
}
|
|
|
|
|
|
|
|
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(
|
2018-06-16 12:48:14 +02:00
|
|
|
&self,
|
2018-06-16 10:48:46 +02:00
|
|
|
client: &reqwest::Client,
|
|
|
|
) -> (IndexMap<String, Vec<String>>, String);
|
2018-06-16 18:13:24 +02:00
|
|
|
fn get_champ_data(&self, id: &str, position: &str, client: &reqwest::Client) -> Option<Value>;
|
2018-06-16 10:48:46 +02:00
|
|
|
|
2018-06-16 18:13:24 +02:00
|
|
|
fn make_item_set(&self, data: &Value, label: &str) -> Value {
|
2018-06-16 10:48:46 +02:00
|
|
|
json!({
|
2019-04-21 22:34:08 +02:00
|
|
|
"items": data["items"].as_array().unwrap().iter().map(|x| json!({"id": x["id"].as_str(), "count": 1})).collect::<Vec<Value>>(),
|
|
|
|
"type": format!("{} ({:.2}% - {} games)", label, data["winPercent"].as_f64().unwrap() * 100., data["games"].as_u64().unwrap())
|
|
|
|
})
|
2018-06-16 10:48:46 +02:00
|
|
|
}
|
|
|
|
|
2018-06-16 18:13:24 +02:00
|
|
|
fn make_item_set_from_list(
|
|
|
|
&self,
|
|
|
|
list: &Vec<u32>,
|
|
|
|
label: &str,
|
|
|
|
key: &str,
|
|
|
|
data: &Value,
|
|
|
|
) -> Value {
|
2018-06-16 10:48:46 +02:00
|
|
|
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::<usize>().unwrap() - 1]["key"]
|
|
|
|
.as_str()
|
|
|
|
.unwrap()
|
|
|
|
})
|
|
|
|
.collect::<Vec<&str>>()
|
|
|
|
.join(".");
|
|
|
|
}
|
|
|
|
json!({
|
2019-04-21 22:34:08 +02:00
|
|
|
"items": list.iter().map(|x| json!({"id": x.to_string(), "count": 1})).collect::<Vec<Value>>(),
|
|
|
|
"type": format!("{} {}", label, key_order)
|
|
|
|
})
|
2018-06-16 10:48:46 +02:00
|
|
|
}
|
|
|
|
fn write_item_set(
|
2018-06-16 12:48:14 +02:00
|
|
|
&self,
|
2018-06-16 10:48:46 +02:00
|
|
|
id: &str,
|
|
|
|
name: &str,
|
|
|
|
pos: &str,
|
|
|
|
ver: &str,
|
|
|
|
path: &PathBuf,
|
|
|
|
client: &reqwest::Client,
|
|
|
|
) {
|
|
|
|
info!("Retrieving data for {} at {}", name, pos);
|
2018-06-16 18:13:24 +02:00
|
|
|
let data = self.get_champ_data(id, pos, client);
|
2018-06-16 10:48:46 +02:00
|
|
|
|
|
|
|
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
|
2018-06-16 18:13:24 +02:00
|
|
|
.push(self.make_item_set(&data[&path[0]][&path[1]], label));
|
2018-06-16 10:48:46 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-06-16 18:13:24 +02:00
|
|
|
item_set.blocks.push(self.make_item_set_from_list(
|
2018-06-16 10:48:46 +02:00
|
|
|
&CONSUMABLES.to_vec(),
|
|
|
|
"Consumables | Frequent:",
|
|
|
|
"mostGames",
|
|
|
|
&data,
|
|
|
|
));
|
2018-06-16 18:13:24 +02:00
|
|
|
item_set.blocks.push(self.make_item_set_from_list(
|
2018-06-16 10:48:46 +02:00
|
|
|
&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(),
|
2019-04-21 22:34:08 +02:00
|
|
|
)
|
|
|
|
.unwrap();
|
2018-06-16 10:48:46 +02:00
|
|
|
}
|
|
|
|
None => {
|
|
|
|
error!("Can't get data for {} at {}", id, pos);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|