use clap::Parser; use rand::Rng; use reqwest::{ header::{HeaderMap, HeaderValue}, Method, }; use std::{collections::HashMap, time::Duration}; const API: &'static str = "https://leekwars.com/api/"; #[derive(Parser)] #[command(name = "leekwarsbot")] #[command(bin_name = "leekwarsbot")] struct Cli { #[clap(short, long)] username: String, /// Number of seconds to wait between each fight #[clap(short, long, default_value_t = 10)] delay: u64, /// Number of fights to start #[clap(short, long, default_value_t = 1)] fights: usize, } fn main() { let cli = Cli::parse(); let delay = std::time::Duration::from_secs(cli.delay); let mut rng = rand::thread_rng(); let password = passterm::prompt_password_tty(Some("Password: ")).unwrap(); let client = reqwest::blocking::Client::builder() .timeout(Duration::from_secs(30)) .user_agent("RustyLeekwarsBot") .build() .unwrap(); let mut form = HashMap::new(); form.insert("login", cli.username.as_str()); form.insert("password", password.as_str()); let resp = client .post(format!("{}{}", API, "farmer/login-token")) .form(&form) .send() .unwrap(); //dbg!(resp.status()); //dbg!(resp.headers()); let phpsessid = resp .cookies() .find_map(|cookie| { if cookie.name() == "PHPSESSID" && cookie.value() != "deleted" { Some(cookie.value().to_owned()) } else { None } }) .expect("No PHPSESSID from the API!"); let token = resp .cookies() .find_map(|cookie| { if cookie.name() == "token" && cookie.value() != "deleted" { Some(cookie.value().to_owned()) } else { None } }) .expect("No token from the API!"); let mut headers = HeaderMap::new(); headers.insert( reqwest::header::AUTHORIZATION, HeaderValue::from_str(&format!("Bearer {}", token)).unwrap(), ); headers.insert( reqwest::header::COOKIE, HeaderValue::from_str(&format!("token={}; PHPSESSID={}", token, phpsessid)).unwrap(), ); for _ in 0..cli.fights { let resp: serde_json::Value = client .request( Method::GET, format!("{}{}", API, "garden/get-farmer-opponents"), ) .headers(headers.clone()) .send() .unwrap() .json() .unwrap(); //dbg!(&resp); let opponent = &resp["opponents"].as_array().unwrap()[rng.gen_range(0..5)]; let opponent_name = opponent["name"].as_str().unwrap(); let opponent_id = opponent["id"].as_u64().unwrap(); println!("Start farmer fight against: {opponent_id} `{opponent_name}`"); let mut map = HashMap::<&str, u64>::new(); map.insert("target_id", opponent_id); let _resp: serde_json::Value = client .request( Method::POST, format!("{}{}", API, "garden/start-farmer-fight"), ) .headers(headers.clone()) .json(&map) .send() .unwrap() .json() .unwrap(); //dbg!(resp); std::thread::sleep(delay); } }