extern crate telegram_bot; extern crate futures; extern crate tokio_core; extern crate serde; extern crate serde_json; extern crate chrono; use std::io::Read; use std::io::Write; use crate::futures::Stream; use tokio_core::reactor::Core; use std::env; use telegram_bot::*; use chrono::prelude::*; use std::sync::*; use std::collections::HashMap; const SCORE_FILE_PATH : &str = "score.json"; fn main() { let mut core = Core::new().unwrap(); let token = env::var("TELEGRAM_BOT_TOKEN").unwrap(); let api = Api::configure(token).build(core.handle()).unwrap(); let leet_time = NaiveTime::from_hms(13, 37, 30); let scores : Arc>> = Arc::new(Mutex::new(HashMap::new())); let time_scored : Arc>>> = Arc::new(Mutex::new(HashMap::new())); { if let Ok(mut score_file) = std::fs::File::open(SCORE_FILE_PATH) { let mut json_str = String::new(); score_file.read_to_string(&mut json_str).expect("Failed to read score file"); let mut map = scores.lock().unwrap(); *map = serde_json::from_str(&json_str).expect("Failed to deserialize scores"); } } { let scores = scores.clone(); std::thread::spawn(move || { loop { { let map = scores.lock().unwrap(); let json_str = serde_json::to_string(&*map).unwrap(); let mut score_file = std::fs::File::create(SCORE_FILE_PATH).expect("Unable to open or create file"); score_file.write_all(json_str.as_bytes()).expect("unable to write to score file!"); } println!("written score file"); std::thread::sleep(std::time::Duration::from_secs(5*60)); } }); } let future = api.stream().for_each(|update| { if let UpdateKind::Message(message) = update.kind { if let MessageKind::Text {ref data, ..} = message.kind { println!("<{}>: {}", message.from.first_name, data); let current_time = Local::now().time(); let allowed_timegap = 30; if data.to_lowercase() == "leet" || data == "1337" { dbg!(data); let leet_distance = (current_time - leet_time).num_seconds().abs(); if leet_distance > allowed_timegap { api.spawn(message.text_reply( "It is not leet right now".to_string() )); } else { let mut time_scored_map = time_scored.lock().unwrap(); let time_scored = time_scored_map.entry(message.from.first_name.clone()).or_insert(Local.timestamp(0,0)); let time_scored_distance = (Local::now() - *time_scored).num_seconds().abs(); if time_scored_distance < allowed_timegap * 4 { api.spawn(message.text_reply( "You already hit leet today you dumbass, don't try to cheat!".to_string() )); } else { let mut map = scores.lock().unwrap(); let entry = map.entry(message.from.first_name.clone()).or_insert(0); *entry += 1; *time_scored = Local::now(); api.spawn(message.text_reply( format!("{} just hit leet! New score: {}", message.from.first_name, *entry) )); let current_leet_count = time_scored_map.iter().filter(|(_,t)| (**t - Local::now()).num_seconds() < allowed_timegap * 2).count(); if current_leet_count == 3 { api.spawn(message.chat.text("OH BABY A TRIPPLE!!!")); } } } } else if data == "-score" { let map = scores.lock().unwrap(); let json = serde_json::to_string(&*map).unwrap(); api.spawn(message.text_reply( format!("Score json: {}", json) )); } else if data == "-time" { api.spawn(message.text_reply( format!("local time: {}, leet time: {}, time distance to leet: {:#?}", current_time, leet_time, (current_time - leet_time).num_seconds()) )); } } } Ok(()) }); core.run(future).unwrap(); }