//! GuruConnect Agent - Remote Desktop Agent for Windows //! //! Provides screen capture, input injection, and remote control capabilities. //! //! Usage: //! guruconnect-agent.exe [support_code] //! //! If a support code is provided, the agent will connect using that code //! for a one-time support session. mod capture; mod config; mod encoder; mod input; mod session; mod transport; pub mod proto { include!(concat!(env!("OUT_DIR"), "/guruconnect.rs")); } use anyhow::Result; use tracing::{info, error, Level}; use tracing_subscriber::FmtSubscriber; #[tokio::main] async fn main() -> Result<()> { // Initialize logging let subscriber = FmtSubscriber::builder() .with_max_level(Level::INFO) .with_target(true) .with_thread_ids(true) .init(); info!("GuruConnect Agent v{}", env!("CARGO_PKG_VERSION")); // Parse command line arguments let args: Vec = std::env::args().collect(); let support_code = if args.len() > 1 { let code = args[1].trim().to_string(); // Validate it looks like a 6-digit code if code.len() == 6 && code.chars().all(|c| c.is_ascii_digit()) { info!("Support code provided: {}", code); Some(code) } else { info!("Invalid support code format, ignoring: {}", code); None } } else { None }; // Load configuration let mut config = config::Config::load()?; config.support_code = support_code; info!("Loaded configuration for server: {}", config.server_url); // Run the agent if let Err(e) = run_agent(config).await { error!("Agent error: {}", e); return Err(e); } Ok(()) } async fn run_agent(config: config::Config) -> Result<()> { // Create session manager let mut session = session::SessionManager::new(config.clone()); // Connect to server and run main loop loop { info!("Connecting to server..."); match session.connect().await { Ok(_) => { info!("Connected to server"); // Run session until disconnect if let Err(e) = session.run().await { error!("Session error: {}", e); } } Err(e) => { error!("Connection failed: {}", e); } } // Wait before reconnecting info!("Reconnecting in 5 seconds..."); tokio::time::sleep(tokio::time::Duration::from_secs(5)).await; } }