//! Implements reader and writer to use when talking to UE2 game server. use std::error::Error; use std::io::{Read, Write}; use std::net::{SocketAddr, TcpListener}; use std::sync::Arc; use std::{str, thread}; mod reader; mod writer; pub use reader::MessageReader; pub use writer::MessageWriter; pub struct Link { reader: MessageReader, writer: MessageWriter, } impl Link { pub fn run(port: u16, handler: F) -> Result<(), Box> where F: Fn(&mut Link, &str) -> () + Send + Sync + 'static, { let address = SocketAddr::from(([0, 0, 0, 0], port)); let listener = TcpListener::bind(address)?; let handler = Arc::new(handler); loop { // Listen to new (multiple) connection let mut reading_stream = listener.accept()?.0; let mut writing_stream = reading_stream.try_clone()?; let mut avarice_link = Link { reader: MessageReader::new(), writer: MessageWriter::new(), }; let handler_clone = handler.clone(); // On connection - spawn a new thread thread::spawn(move || loop { let mut buffer = [0; 1024]; // Reading cycle match reading_stream.read(&mut buffer) { Ok(n) => avarice_link.reader.push(&buffer[..n]).unwrap(), _ => panic!("Connection issue!"), }; // Handling cycle while let Some(message) = avarice_link.reader.pop() { handler_clone(&mut avarice_link, &message); } // Writing avarice_link .writer .update_ue_received_bytes(avarice_link.reader.ue_received_bytes()); if let Some(bytes) = avarice_link.writer.try_pop() { writing_stream.write_all(&bytes).unwrap(); } }); } } pub fn write(&mut self, message: &str) { self.writer.push(message); } }