use std::net::{TcpListener, TcpStream, SocketAddr, Ipv4Addr}; use std::thread; use elseware::common::{send_packet, recv_packet, PacketNetworkError}; use rand::{Rng, RngCore}; use libpso::{PacketParseError, PSOPacket}; use libpso::patch::packet::*; use libpso::crypto::{CipherError, PSOCipher, NullCipher}; use libpso::crypto::pc::PSOPCCipher; const PATCH_PORT: u16 = 11000; #[derive(Debug)] enum PatchError { PacketNetworkError(PacketNetworkError) } impl From for PatchError { fn from(err: PacketNetworkError) -> PatchError { PatchError::PacketNetworkError(err) } } #[derive(Debug)] pub enum PatchPacket { PatchWelcomeReply(PatchWelcomeReply), StartFilePatching(StartFilePatching), } struct Client { running: bool, key_in: u32, key_out: u32, socket: TcpStream, cipher_in: Box, cipher_out: Box, } impl Client { fn new(socket: TcpStream) -> Client { let mut rng = rand::thread_rng(); let key_in: u32 = rng.gen(); let key_out: u32 = rng.gen(); Client { running: true, key_in: key_in, key_out: key_out, socket: socket, cipher_in: Box::new(NullCipher {}), cipher_out: Box::new(NullCipher {}), //cipher_in: Box::new(PSOPCCipher::new(key_in)), //cipher_out: Box::new(PSOPCCipher::new(key_out)), } } fn send(&mut self, pkt: &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; } } } fn handle_packet(&mut self, patch_pkt: &PatchPacket) -> Result<(), PatchError> { println!("[patch] recv({:?}): {:?}", self.socket, patch_pkt); match patch_pkt { PatchPacket::PatchWelcomeReply(pkt) => { }, PatchPacket::StartFilePatching(pkt) => { }, } Ok(()) } fn run(mut self) { let welcome_pkt = PatchWelcome::new(self.key_out, self.key_in); self.send(&welcome_pkt); self.cipher_in = Box::new(PSOPCCipher::new(self.key_in)); self.cipher_out = Box::new(PSOPCCipher::new(self.key_out)); while self.running { let res = recv_packet(&mut self.socket, &mut *self.cipher_in) .and_then(|pkt| { PatchPacket::from_bytes(&pkt) .map_err(|err| err.into()) }) .map(|pkt| { self.handle_packet(&pkt) }); println!("res! {:?}", res); match res { Ok(_) => {}, Err(err) => { println!("[patch] error handling packet with {:?}: {:?}", self.socket, err); self.running = false; } } /*.or_else(|err| { println!("[patch] error handling packet with {:?}: {:?}", self.socket, err); self.running = false; })?;*/ } } } impl PatchPacket { pub fn from_bytes(data: &Vec) -> Result { match data[2] { 0x02 => Ok(PatchPacket::PatchWelcomeReply(PatchWelcomeReply::from_bytes(data)?)), 0x04 => Ok(PatchPacket::StartFilePatching(StartFilePatching::from_bytes(data)?)), _ => Err(PacketParseError::WrongPacketForServerType) } } } fn handle_client(socket: TcpStream) { let client = Client::new(socket); client.run(); } pub fn patch_server_loop() { println!("[patch] starting server"); let listener = TcpListener::bind(&SocketAddr::from((Ipv4Addr::new(0,0,0,0), PATCH_PORT))).unwrap(); loop { match listener.accept() { Ok((socket, addr)) => { println!("[patch] accepted connection: {}", addr); thread::spawn(move || { handle_client(socket); }); } Err(e) => { println!("[patch] accepted connection error {:?}", e); } } } }