use libpso::crypto::{PSOCipher, NullCipher}; use libpso::{PSOPacket, PacketParseError}; use crate::common::serverstate::{ServerState, ServerPacket, OnConnect}; use crate::common::network::{send_packet, recv_packet}; use std::net; use mio::tcp::TcpStream; use mio::{Poll, Events, Token, Ready, PollOpt}; pub struct Client { running: bool, socket: mio::tcp::TcpStream, cipher_in: Box, cipher_out: Box, state: Box>, } impl Client { pub fn new(socket: net::TcpStream, state: Box>) -> Client { let mut client = Client { running: true, socket: mio::tcp::TcpStream::from_stream(socket).expect("could not convert socket to nonblocking"), cipher_in: Box::new(NullCipher {}), cipher_out: Box::new(NullCipher {}), state: state, }; for task in client.state.on_connect() { match task { OnConnect::Packet(pkt) => client.send(&*pkt), OnConnect::Cipher((cipher_in, cipher_out)) => { client.cipher_in = cipher_in; client.cipher_out = cipher_out; }, } } client } fn send(&mut self, pkt: &dyn PSOPacket) { match send_packet(&mut self.socket, &mut *self.cipher_out, pkt) { Ok(_) => { println!("[patch] send ({:?}): {:?}", self.socket, pkt); }, Err(err) => { println!("[patch] error sending packet to {:?}: {:?}", self.socket, err); self.running = false; } } } pub fn io_loop(mut self) { let poll = mio::Poll::new().unwrap(); poll.register(&self.socket, Token(0), Ready::readable(), PollOpt::edge()).unwrap(); let mut events = Events::with_capacity(1024); loop { poll.poll(&mut events, None).unwrap(); for event in &events{ println!("event! {:?}", event); if event.token() == Token(0) { loop { let pkt = recv_packet(&mut self.socket, &mut *self.cipher_in) .and_then(|pkt| { P::from_bytes(&pkt) .map_err(|err| err.into()) }); match pkt { Ok(pkt) => { let response = self.state.handle(&pkt); for r in response { self.send(&*r); } }, Err(err) => { println!("error recv-ing packet with {:?}: {:?}", self.socket, err); break; } } } } } } } }