use std::io::{Read, Write}; use std::net::TcpListener; use std::sync::Arc; use std::thread; use std::time::{Duration, Instant}; use color_eyre::eyre::Result; use log::{debug, error}; fn main() -> Result<()> { color_eyre::install()?; simplelog::TermLogger::init( simplelog::LevelFilter::Trace, simplelog::Config::default(), simplelog::TerminalMode::Mixed, simplelog::ColorChoice::Auto, ) .unwrap(); let listener = TcpListener::bind("0.0.0.0:3305")?; debug!("Listening for clients..."); let start_time = Arc::new(Instant::now()); for stream in listener.incoming() { match stream { Ok(mut stream) => { debug!("Got connection!"); let start_time = start_time.clone(); thread::spawn(move || loop { debug!("Sending ping..."); let mut buf = [0; 16]; let before = start_time.elapsed().as_micros() as i128; stream .write_all(&[&[0][..], &before.to_be_bytes()[..]].concat()) .unwrap(); stream.read_exact(&mut buf).unwrap(); let after = start_time.elapsed().as_micros() as i128; let client_time = i128::from_be_bytes(buf); let adjustment = (before + after) / 2 - client_time; debug!( "Client time: {}/{}, Old server time: {}, New server time: {}/{}, Calculated adjustment: {}", client_time, client_time-before, before, after, after-before, adjustment, ); stream .write_all(&[&[1][..], &adjustment.to_be_bytes()[..]].concat()) .unwrap(); thread::sleep(Duration::from_secs(1)); }); } Err(e) => { error!("Receiving connection failed: {e}"); } } } Ok(()) }