2018-06-09 12:35:47 +02:00
|
|
|
use indexmap::IndexMap;
|
2020-11-20 08:15:50 +01:00
|
|
|
use log::{error, info, LevelFilter};
|
2019-09-30 17:56:03 +02:00
|
|
|
use serde_derive::Deserialize;
|
2020-11-20 08:15:50 +01:00
|
|
|
use simple_logger::SimpleLogger;
|
2021-03-14 14:47:26 +01:00
|
|
|
#[cfg(target_os = "windows")]
|
2021-03-14 13:06:29 +01:00
|
|
|
use std::io;
|
2021-03-10 12:22:00 +01:00
|
|
|
use std::io::Error;
|
|
|
|
#[cfg(target_os = "windows")]
|
|
|
|
use std::io::ErrorKind;
|
2018-06-09 09:07:41 +02:00
|
|
|
use std::path::PathBuf;
|
2018-06-10 15:02:08 +02:00
|
|
|
use std::{fs, thread, time};
|
2018-06-09 00:06:30 +02:00
|
|
|
use time::Duration;
|
2020-06-28 18:34:31 +02:00
|
|
|
#[cfg(target_os = "windows")]
|
2018-06-09 08:31:15 +02:00
|
|
|
use winreg::RegKey;
|
2019-09-26 22:39:25 +02:00
|
|
|
|
|
|
|
mod cgg_data_source;
|
|
|
|
mod data_source;
|
2019-09-30 17:56:03 +02:00
|
|
|
mod kb_data_source;
|
2019-09-26 22:39:25 +02:00
|
|
|
mod pb_data_source;
|
|
|
|
|
2021-03-13 23:02:26 +01:00
|
|
|
use cgg_data_source::CGGDataSource;
|
2019-09-26 22:39:25 +02:00
|
|
|
use data_source::DataSource;
|
2019-09-30 17:56:03 +02:00
|
|
|
use kb_data_source::KBDataSource;
|
|
|
|
use pb_data_source::PBDataSource;
|
2018-06-04 22:51:18 +02:00
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
struct Realm {
|
2018-06-09 09:07:41 +02:00
|
|
|
v: String,
|
2018-06-04 22:51:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
|
|
|
struct Champion {
|
2018-06-09 12:35:47 +02:00
|
|
|
data: IndexMap<String, ChampInfo>,
|
2018-06-04 22:51:18 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Deserialize)]
|
2021-03-13 23:02:26 +01:00
|
|
|
pub struct ChampInfo {
|
|
|
|
id: String,
|
2018-06-09 11:46:02 +02:00
|
|
|
name: String,
|
2021-03-14 11:21:57 +01:00
|
|
|
key: String,
|
2018-06-07 22:39:25 +02:00
|
|
|
}
|
|
|
|
|
2021-03-10 12:22:00 +01:00
|
|
|
const USER_AGENT_KEY: &str = "User-Agent";
|
|
|
|
const USER_AGENT_VALUE: &str =
|
2021-03-13 23:02:26 +01:00
|
|
|
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:87.0) Gecko/20100101 Firefox/87.0";
|
2018-06-07 22:39:25 +02:00
|
|
|
const LOL_CHAMPS_DIR: &str = ".\\champs";
|
2018-06-08 22:41:01 +02:00
|
|
|
|
2021-03-15 07:46:48 +01:00
|
|
|
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
2021-03-07 18:02:11 +01:00
|
|
|
SimpleLogger::new()
|
|
|
|
.with_level(LevelFilter::Info)
|
2021-03-10 12:22:00 +01:00
|
|
|
.with_module_level("ureq", LevelFilter::Error)
|
2021-03-15 07:46:48 +01:00
|
|
|
.init()?;
|
2018-06-04 22:51:18 +02:00
|
|
|
|
|
|
|
info!("CGG Item Sets");
|
|
|
|
|
2018-06-09 08:31:15 +02:00
|
|
|
let lol_champs_dir = match lol_champ_dir() {
|
|
|
|
Ok(x) => x,
|
2018-06-09 09:07:41 +02:00
|
|
|
Err(_e) => PathBuf::from(LOL_CHAMPS_DIR),
|
2018-06-09 08:31:15 +02:00
|
|
|
};
|
2021-03-15 07:46:48 +01:00
|
|
|
info!("LoL Champs Folder: {}", lol_champs_dir.to_str().unwrap_or(LOL_CHAMPS_DIR));
|
2018-06-09 08:31:15 +02:00
|
|
|
|
2021-03-10 12:22:00 +01:00
|
|
|
let client = ureq::AgentBuilder::new()
|
2018-06-09 00:06:30 +02:00
|
|
|
.timeout(Duration::from_secs(10))
|
2021-03-10 12:22:00 +01:00
|
|
|
.build();
|
2018-06-04 22:51:18 +02:00
|
|
|
|
2018-06-09 09:07:41 +02:00
|
|
|
let realm: Realm = client
|
|
|
|
.get("https://ddragon.leagueoflegends.com/realms/euw.json")
|
2021-03-10 12:22:00 +01:00
|
|
|
.set(USER_AGENT_KEY, USER_AGENT_VALUE)
|
2021-03-15 07:46:48 +01:00
|
|
|
.call()?
|
|
|
|
.into_json()?;
|
2018-06-04 22:51:18 +02:00
|
|
|
info!("LoL version: {}", realm.v);
|
|
|
|
|
2018-06-09 09:07:41 +02:00
|
|
|
let champion: Champion = client
|
|
|
|
.get(&format!(
|
|
|
|
"https://ddragon.leagueoflegends.com/cdn/{}/data/en_US/champion.json",
|
|
|
|
realm.v
|
|
|
|
))
|
2021-03-10 12:22:00 +01:00
|
|
|
.set(USER_AGENT_KEY, USER_AGENT_VALUE)
|
2021-03-15 07:46:48 +01:00
|
|
|
.call()?
|
|
|
|
.into_json()?;
|
2018-06-04 22:51:18 +02:00
|
|
|
info!("LoL numbers of champs: {}", champion.data.len());
|
2018-06-05 00:02:35 +02:00
|
|
|
|
2021-03-13 23:02:26 +01:00
|
|
|
let data_sources: [Box<dyn DataSource>; 3] = [
|
2019-09-30 17:56:03 +02:00
|
|
|
Box::new(PBDataSource),
|
2021-03-13 23:02:26 +01:00
|
|
|
Box::new(CGGDataSource),
|
2019-09-30 17:56:03 +02:00
|
|
|
Box::new(KBDataSource::new(&client)),
|
|
|
|
];
|
2018-06-16 12:48:14 +02:00
|
|
|
|
|
|
|
for data_source in data_sources.iter() {
|
|
|
|
let (champs, patch) = data_source.get_champs_with_positions_and_patch(&client);
|
|
|
|
|
2019-09-30 17:56:03 +02:00
|
|
|
info!("{} version: {}", data_source.get_alias(), patch);
|
|
|
|
info!(
|
|
|
|
"{} numbers of champs: {}",
|
|
|
|
data_source.get_alias(),
|
|
|
|
champs.len()
|
|
|
|
);
|
2018-06-16 12:48:14 +02:00
|
|
|
|
|
|
|
for (id, positions) in &champs {
|
2021-03-14 14:57:31 +01:00
|
|
|
let mut champ_id: String = id.to_owned();
|
2021-03-13 23:02:26 +01:00
|
|
|
|
|
|
|
if !champion.data.contains_key(&champ_id) {
|
|
|
|
champ_id = get_champ_from_key(&champion, &champ_id);
|
|
|
|
}
|
2021-03-14 12:33:04 +01:00
|
|
|
|
2021-03-13 23:02:26 +01:00
|
|
|
if champion.data.contains_key(&champ_id) {
|
|
|
|
let path = lol_champs_dir.join(&champ_id).join("Recommended");
|
2018-06-16 12:48:14 +02:00
|
|
|
fs::create_dir_all(&path).unwrap();
|
2021-03-14 12:33:04 +01:00
|
|
|
if positions.is_empty() {
|
2021-03-14 13:06:29 +01:00
|
|
|
error!("{} missing positions", &champ_id);
|
2021-03-14 12:33:04 +01:00
|
|
|
}
|
2018-06-16 12:48:14 +02:00
|
|
|
for pos in positions {
|
|
|
|
data_source.write_item_set(
|
2021-03-13 23:02:26 +01:00
|
|
|
&champion.data.get(&champ_id).unwrap(),
|
2018-06-16 12:48:14 +02:00
|
|
|
&pos,
|
|
|
|
&patch,
|
|
|
|
&path,
|
|
|
|
&client,
|
|
|
|
);
|
2021-03-14 09:49:18 +01:00
|
|
|
thread::sleep(Duration::from_millis(data_source.get_timeout()));
|
2018-06-16 12:48:14 +02:00
|
|
|
}
|
|
|
|
} else {
|
2021-03-14 12:33:04 +01:00
|
|
|
error!("{} not found in LoL champs", &champ_id);
|
2018-06-07 22:39:25 +02:00
|
|
|
}
|
2018-06-05 00:02:35 +02:00
|
|
|
}
|
|
|
|
}
|
2021-03-15 07:46:48 +01:00
|
|
|
Ok(())
|
2018-06-05 00:02:35 +02:00
|
|
|
}
|
|
|
|
|
2021-03-14 11:21:57 +01:00
|
|
|
fn get_champ_from_key(champs: &Champion, key: &str) -> String {
|
2021-03-13 23:02:26 +01:00
|
|
|
for champ in champs.data.values() {
|
2021-03-14 11:12:42 +01:00
|
|
|
if key == champ.key {
|
2021-03-14 14:57:31 +01:00
|
|
|
return champ.id.to_owned();
|
2021-03-13 23:02:26 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
String::new()
|
|
|
|
}
|
|
|
|
|
2020-06-28 18:34:31 +02:00
|
|
|
#[cfg(target_os = "windows")]
|
2018-06-10 15:02:08 +02:00
|
|
|
fn lol_champ_dir() -> Result<PathBuf, Error> {
|
2021-03-14 13:06:29 +01:00
|
|
|
let hklm = RegKey::predef(winreg::enums::HKEY_LOCAL_MACHINE);
|
|
|
|
|
|
|
|
let node = hklm.open_subkey(r"SOFTWARE\WOW6432Node\Riot Games\RADS");
|
|
|
|
if node.is_ok() {
|
|
|
|
let val: String = node?.get_value("LocalRootFolder")?;
|
|
|
|
return Ok(PathBuf::from(val).parent().unwrap().to_path_buf());
|
|
|
|
} else {
|
|
|
|
let node = hklm.open_subkey(r"SOFTWARE\WOW6432Node\Riot Games, Inc\League of Legends");
|
|
|
|
if node.is_ok() {
|
|
|
|
let val: String = node?.get_value("Location")?;
|
|
|
|
return Ok(PathBuf::from(val));
|
|
|
|
}
|
|
|
|
}
|
2018-06-10 15:02:08 +02:00
|
|
|
|
2021-03-14 13:06:29 +01:00
|
|
|
let node = hklm.open_subkey(r"SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall");
|
|
|
|
let mut sub_node: io::Result<RegKey> = Err(Error::from(ErrorKind::NotFound));
|
|
|
|
|
2021-03-14 13:10:04 +01:00
|
|
|
if let Ok(n) = node {
|
2021-03-14 13:06:29 +01:00
|
|
|
let key = n
|
|
|
|
.enum_keys()
|
|
|
|
.map(|x| x.unwrap())
|
|
|
|
.find(|x| x.starts_with("League of Legends"));
|
2021-03-14 13:10:04 +01:00
|
|
|
if let Some(k) = key {
|
|
|
|
sub_node = n.open_subkey(k);
|
2021-03-14 13:06:29 +01:00
|
|
|
}
|
2021-03-14 13:10:04 +01:00
|
|
|
}
|
2021-03-14 13:06:29 +01:00
|
|
|
|
|
|
|
if sub_node.is_err() {
|
|
|
|
let hkcu = RegKey::predef(winreg::enums::HKEY_CURRENT_USER);
|
|
|
|
let node = hkcu.open_subkey(r"SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\");
|
2021-03-14 13:10:04 +01:00
|
|
|
if let Ok(n) = node {
|
2021-03-14 13:06:29 +01:00
|
|
|
let key = n
|
|
|
|
.enum_keys()
|
|
|
|
.map(|x| x.unwrap())
|
|
|
|
.find(|x| x == "Riot Game league_of_legends.live");
|
2021-03-14 13:10:04 +01:00
|
|
|
if let Some(k) = key {
|
|
|
|
sub_node = n.open_subkey(k);
|
2021-03-14 13:06:29 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-14 09:23:54 +01:00
|
|
|
|
2021-03-14 13:06:29 +01:00
|
|
|
if sub_node.is_ok() {
|
|
|
|
let val: String = sub_node?.get_value("InstallLocation")?;
|
|
|
|
return Ok(PathBuf::from(val).join("Config").join("Champions"));
|
2018-06-10 12:42:02 +02:00
|
|
|
}
|
2021-03-14 09:23:54 +01:00
|
|
|
|
2021-03-14 13:06:29 +01:00
|
|
|
Err(Error::from(ErrorKind::NotFound))
|
2018-06-09 08:31:15 +02:00
|
|
|
}
|
2020-06-28 18:34:31 +02:00
|
|
|
|
|
|
|
#[cfg(not(target_os = "windows"))]
|
|
|
|
fn lol_champ_dir() -> Result<PathBuf, Error> {
|
2021-03-14 09:23:54 +01:00
|
|
|
Ok(PathBuf::from(LOL_CHAMPS_DIR))
|
2020-06-28 18:34:31 +02:00
|
|
|
}
|