elseware/src/common/client.rs
2019-09-13 19:18:42 -07:00

128 lines
4.0 KiB
Rust

use libpso::crypto::{PSOCipher, NullCipher};
use libpso::{PSOPacket, PacketParseError};
use crate::common::serverstate::{ServerState, SendServerPacket, RecvServerPacket, OnConnect, ClientId};
use crate::common::network::{recv_packet, PacketNetworkError};
use std::net;
use std::io::{Read, Write};
use mio::tcp::TcpStream;
use mio::{Poll, Events, Token, Ready, PollOpt};
use mio_extras::channel::Sender;
pub struct Client<S, R> {
pub id: ClientId,
running: bool,
pub socket: mio::tcp::TcpStream,
cipher_in: Box<dyn PSOCipher + Send>,
cipher_out: Box<dyn PSOCipher + Send>,
recv_buffer: Vec<u8>,
incoming_data: Vec<u8>,
send_buffer: Vec<u8>,
_s: std::marker::PhantomData<S>,
_r: std::marker::PhantomData<R>,
}
impl<S, R> Client<S, R> where
S: SendServerPacket + std::fmt::Debug,
R: RecvServerPacket + std::fmt::Debug,
{
pub fn new(id: ClientId, socket: mio::tcp::TcpStream) -> Client<S, R>
{
Client {
id: id,
running: true,
socket: socket,
cipher_in: Box::new(NullCipher {}),
cipher_out: Box::new(NullCipher {}),
recv_buffer: Vec::with_capacity(32),
incoming_data: Vec::new(),
send_buffer: Vec::new(),
_s: std::marker::PhantomData,
_r: std::marker::PhantomData,
}
}
pub fn set_cipher(&mut self, cin: Box<dyn PSOCipher + Send>, out: Box<dyn PSOCipher + Send>) {
self.cipher_in = cin;
self.cipher_out = out;
}
pub fn send_data(&mut self) {
if self.send_buffer.len() == 0 {
return;
}
match self.socket.write(&self.send_buffer) {
Ok(len) => {
if len == 0 {
self.running = false;
}
self.send_buffer.drain(..len);
},
Err(err) => {
println!("[client] error sending data to {:?}: {:?}", self.socket, err);
}
}
}
fn read_data_into_buffer(&mut self) -> Result<(), PacketNetworkError> {
let mut new_data = [0u8; 0x8000];
let len = self.socket.read(&mut new_data)?;
if len == 0 {
return Err(PacketNetworkError::ClientDisconnected);
}
self.recv_buffer.extend_from_slice(&mut new_data[..len]);
let block_chunk_len = self.recv_buffer.len() / self.cipher_in.block_size() * self.cipher_in.block_size();
let buf = self.recv_buffer.drain(..block_chunk_len).collect();
let mut dec_buf = self.cipher_in.decrypt(&buf)?;
self.incoming_data.append(&mut dec_buf);
Ok(())
}
pub fn read_pkts(&mut self) -> Result<Vec<R>, PacketNetworkError> {
self.read_data_into_buffer()?;
let mut result = Vec::new();
loop {
if self.incoming_data.len() < 2 {
break;
}
let pkt_size = u16::from_le_bytes([self.incoming_data[0], self.incoming_data[1]]) as usize;
let mut pkt_len = pkt_size;
while pkt_len % self.cipher_in.block_size() != 0 {
pkt_len += 1;
}
if pkt_len > self.incoming_data.len() {
break;
}
let pkt_data = self.incoming_data.drain(..pkt_len).collect::<Vec<_>>();
println!("[recv: buf] {:?}", pkt_data);
let pkt = R::from_bytes(&pkt_data[..pkt_size])
.map_err(|err| -> PacketNetworkError { err.into() })?;
println!("[recv] {:?}", pkt);
result.push(pkt);
}
Ok(result)
}
pub fn send_pkt(&mut self, pkt: S) {
println!("[send] {:?}", pkt);
let buf = pkt.as_bytes();
if buf.len() < 1024*2 {
println!("[send: buf] {:?}", buf);
}
else {
println!("[send: buf] [...large buffer...]");
}
let mut cbuf = self.cipher_out.encrypt(&buf).unwrap();
self.send_buffer.append(&mut cbuf);
self.send_data();
}
}