use std::{error::Error, io::{Read, Write}, net::TcpStream, sync::{Arc, RwLock}, thread, time::Duration}; use super::{ADVERTISEMENT, ADVERTISEMENT_ENABLED, term::print_console, UPDATE_TIME}; pub fn send_message(host: &str, message: &str) -> Result<(), Box> { let mut stream = TcpStream::connect(host)?; stream.write_all(&[0x01])?; let data = format!("\r\x07{}{}{}", message, if message.chars().count() < 39 { " ".repeat(39-message.chars().count()) } else { String::new() }, if ADVERTISEMENT_ENABLED {ADVERTISEMENT} else {""} ); stream.write_all(data.as_bytes())?; Ok(()) } fn skip_null(stream: &mut TcpStream) -> Result, Box> { loop { let mut buf = vec![0; 1]; stream.read_exact(&mut buf)?; if buf[0] != 0 { break Ok(buf) } } } fn read_messages(host: &str) -> Result> { let mut stream = TcpStream::connect(host)?; stream.write_all(&[0x00])?; let packet_size = { let mut data = skip_null(&mut stream)?; loop { let mut buf = vec![0; 1]; stream.read_exact(&mut buf)?; let ch = buf[0]; if ch == 0 { break } data.push(ch); } String::from_utf8(data)? .trim_matches(char::from(0)) .parse()? }; stream.write_all(&[0x01])?; let packet_data = { let mut data = skip_null(&mut stream)?; while data.len() < packet_size { let mut buf = vec![0; packet_size - data.len()]; let read_bytes = stream.read(&mut buf)?; buf.truncate(read_bytes); data.append(&mut buf); } String::from_utf8_lossy(&data).to_string() }; Ok(packet_data) } fn recv_loop(host: &str, cache: Arc>, input: Arc>) -> Result<(), Box> { while let Ok(data) = read_messages(host) { if data == cache.read().unwrap().clone() { continue } *cache.write().unwrap() = data; print_console(&cache.read().unwrap(), &input.read().unwrap())?; thread::sleep(Duration::from_millis(UPDATE_TIME)); } Ok(()) } pub fn run_recv_loop(host: String, messages: Arc>, input: Arc>) { thread::spawn({ move || { let _ = recv_loop(&host, messages, input); println!("Connection closed"); } }); }