use std::{env, process, time::Duration, fmt::format}; use enigo::KeyboardControllable; use serde::{Deserialize, Serialize}; use serde_json::Result; extern crate paho_mqtt as mqtt; const BROKER: &str = "tcp://broker.emqx.io:1883"; #[derive(Serialize, Deserialize, PartialEq)] enum MqttMessageKind { Time, Confirm, } #[derive(Serialize, Deserialize)] struct MqttMessage { id: uuid::Uuid, kind: MqttMessageKind, time: u32, } fn init_mqtt(uri: &str, topic: &str) -> mqtt::Result<(mqtt::Client, mqtt::Receiver>)> { let create_opts = mqtt::CreateOptionsBuilder::new() .server_uri(uri) .finalize(); // Create a client. let cli = mqtt::Client::new(create_opts)?; // Define the set of options for the connection. let conn_opts = mqtt::ConnectOptionsBuilder::new() .keep_alive_interval(Duration::from_secs(20)) .clean_session(true) .finalize(); let rx = cli.start_consuming(); // Connect and wait for it to complete or fail. cli.connect(conn_opts)?; cli.subscribe(topic, 1)?; Ok((cli, rx)) } fn main() { let password = "test"; let broker_domain = "broker.emqx.io"; let broker_url = format!("tcp://{}:1883", broker_domain); let mut en = enigo::Enigo::new(); let c = crypto_helper::crypto::Crypto::new("test", "broker.emqx.io"); let topic = format!("org.speedclimbing.ok-ready-go.{password}"); let topic = crypto_helper::crypto::Crypto::sha256(&c.encrypt(&topic)); let (cli, rx) = init_mqtt(&broker_url, &topic).unwrap(); println!("Processing requests..."); for msg in rx.iter() { if let Some(msg) = msg { let msg = msg.payload_str(); let msg = c.decrypt(&msg); println!("Got: {}", msg); let msg: MqttMessage = serde_json::from_str(&msg).unwrap(); if msg.kind != MqttMessageKind::Time { continue; } println!("Got time: {} with id {}", msg.time, msg.id); let time_with_comma = format!("{},{}", msg.time / 1000, (msg.time/10) % 100); en.key_sequence(&time_with_comma); en.key_click(enigo::Key::Tab); en.key_click(enigo::Key::Tab); let reply = MqttMessage { id: msg.id, kind: MqttMessageKind::Confirm, time: 0, }; let reply = serde_json::to_string(&reply).unwrap(); let reply = c.encrypt(&reply); println!("Sending reply: {reply}"); let reply = mqtt::Message::new(&topic, reply, 1); cli.publish(reply).expect("publish"); } else if !cli.is_connected() { break; } } }