|
|
@ -5,13 +5,38 @@ use async_std::io::prelude::{ReadExt, WriteExt}; |
|
|
|
use async_std::prelude::{StreamExt};
|
|
|
|
use std::collections::HashMap;
|
|
|
|
|
|
|
|
use libpso::crypto::{PSOCipher, NullCipher};
|
|
|
|
use libpso::crypto::{PSOCipher, NullCipher, CipherError};
|
|
|
|
use libpso::PacketParseError;
|
|
|
|
use crate::common::serverstate::ClientId;
|
|
|
|
use crate::common::serverstate::{RecvServerPacket, SendServerPacket, ServerState, OnConnect};
|
|
|
|
|
|
|
|
|
|
|
|
enum PacketReceiverError {
|
|
|
|
ClientDisconnect,
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum NetworkError {
|
|
|
|
CouldNotSend,
|
|
|
|
CipherError(CipherError),
|
|
|
|
PacketParseError(PacketParseError),
|
|
|
|
IOError(std::io::Error),
|
|
|
|
DataNotReady,
|
|
|
|
ClientDisconnected,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<CipherError> for NetworkError {
|
|
|
|
fn from(err: CipherError) -> NetworkError {
|
|
|
|
NetworkError::CipherError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<std::io::Error> for NetworkError {
|
|
|
|
fn from(err: std::io::Error) -> NetworkError {
|
|
|
|
NetworkError::IOError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<PacketParseError> for NetworkError {
|
|
|
|
fn from(err: PacketParseError) -> NetworkError {
|
|
|
|
NetworkError::PacketParseError(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct PacketReceiver {
|
|
|
@ -31,13 +56,13 @@ impl PacketReceiver { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn fill_recv_buffer(&mut self) -> Result<(), PacketReceiverError>{
|
|
|
|
async fn fill_recv_buffer(&mut self) -> Result<(), NetworkError> {
|
|
|
|
let mut data = [0u8; 0x8000];
|
|
|
|
|
|
|
|
let mut socket = &*self.socket;
|
|
|
|
let len = socket.read(&mut data).await.unwrap();
|
|
|
|
let len = socket.read(&mut data).await?;
|
|
|
|
if len == 0 {
|
|
|
|
return Err(PacketReceiverError::ClientDisconnect);
|
|
|
|
return Err(NetworkError::ClientDisconnected);
|
|
|
|
}
|
|
|
|
|
|
|
|
self.recv_buffer.extend_from_slice(&mut data[..len]);
|
|
|
@ -46,14 +71,14 @@ impl PacketReceiver { |
|
|
|
let mut cipher = self.cipher.lock().await;
|
|
|
|
let block_chunk_len = self.recv_buffer.len() / cipher.block_size() * cipher.block_size();
|
|
|
|
let buf = self.recv_buffer.drain(..block_chunk_len).collect();
|
|
|
|
cipher.decrypt(&buf).unwrap()
|
|
|
|
cipher.decrypt(&buf)?
|
|
|
|
};
|
|
|
|
self.incoming_data.append(&mut dec_buf);
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn recv_pkts<R: RecvServerPacket + Send + std::fmt::Debug>(&mut self) -> Result<Vec<R>, PacketReceiverError> {
|
|
|
|
async fn recv_pkts<R: RecvServerPacket + Send + std::fmt::Debug>(&mut self) -> Result<Vec<R>, NetworkError> {
|
|
|
|
self.fill_recv_buffer().await?;
|
|
|
|
|
|
|
|
let mut result = Vec::new();
|
|
|
@ -89,12 +114,15 @@ impl PacketReceiver { |
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async fn send_pkt<S: SendServerPacket + Send + std::fmt::Debug>(socket: Arc<async_std::net::TcpStream>, cipher: Arc<Mutex<Box<dyn PSOCipher + Send>>>, pkt: S) {
|
|
|
|
async fn send_pkt<S: SendServerPacket + Send + std::fmt::Debug>(socket: Arc<async_std::net::TcpStream>,
|
|
|
|
cipher: Arc<Mutex<Box<dyn PSOCipher + Send>>>, pkt: S)
|
|
|
|
-> Result<(), NetworkError>
|
|
|
|
{
|
|
|
|
let buf = pkt.as_bytes();
|
|
|
|
let cbuf = cipher.lock().await.encrypt(&buf).unwrap();
|
|
|
|
let cbuf = cipher.lock().await.encrypt(&buf)?;
|
|
|
|
let mut ssock = &*socket;
|
|
|
|
ssock.write_all(&cbuf).await;
|
|
|
|
|
|
|
|
ssock.write_all(&cbuf).await?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -118,7 +146,7 @@ async fn server_state_loop<STATE, S, R, E>(mut state: STATE, |
|
|
|
E: std::fmt::Debug + Send,
|
|
|
|
{
|
|
|
|
async_std::task::spawn(async move {
|
|
|
|
let mut clients = HashMap::new();
|
|
|
|
let mut clients = HashMap::new();
|
|
|
|
|
|
|
|
loop {
|
|
|
|
let action = server_state_receiver.recv().await.unwrap();
|
|
|
@ -138,22 +166,31 @@ async fn server_state_loop<STATE, S, R, E>(mut state: STATE, |
|
|
|
}
|
|
|
|
},
|
|
|
|
ClientAction::Packet(client_id, pkt) => {
|
|
|
|
let k = state.handle(client_id, &pkt);
|
|
|
|
let pkts = k.unwrap().collect::<Vec<_>>();
|
|
|
|
for (client_id, pkt) in pkts {
|
|
|
|
let client = clients.get_mut(&client_id).unwrap();
|
|
|
|
client.send(ServerStateAction::Packet(pkt)).await;
|
|
|
|
let pkts = state.handle(client_id, &pkt);
|
|
|
|
match pkts {
|
|
|
|
Ok(pkts) => {
|
|
|
|
for (client_id, pkt) in pkts {
|
|
|
|
if let Some(client) = clients.get_mut(&client_id) {
|
|
|
|
client.send(ServerStateAction::Packet(pkt)).await;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
warn!("[client {:?} state handler error] {:?}", client_id, err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ClientAction::Disconnect(client_id) => {
|
|
|
|
let pkts = state.on_disconnect(client_id);
|
|
|
|
for (client_id, pkt) in pkts {
|
|
|
|
let client = clients.get_mut(&client_id).unwrap();
|
|
|
|
client.send(ServerStateAction::Packet(pkt)).await;
|
|
|
|
if let Some(client) = clients.get_mut(&client_id) {
|
|
|
|
client.send(ServerStateAction::Packet(pkt)).await;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
let client = clients.remove(&client_id).unwrap();
|
|
|
|
client.send(ServerStateAction::Disconnect).await;
|
|
|
|
if let Some(client) = clients.get_mut(&client_id) {
|
|
|
|
client.send(ServerStateAction::Disconnect).await;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -182,11 +219,14 @@ async fn client_recv_loop<S, R>(client_id: ClientId, |
|
|
|
},
|
|
|
|
Err(err) => {
|
|
|
|
match err {
|
|
|
|
PacketReceiverError::ClientDisconnect => {
|
|
|
|
NetworkError::ClientDisconnected => {
|
|
|
|
trace!("[client disconnected] {:?}", client_id);
|
|
|
|
server_sender.send(ClientAction::Disconnect(client_id));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
_ => {
|
|
|
|
warn!("[client {:?} recv error] {:?}", client_id, err);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -213,7 +253,9 @@ async fn client_send_loop<S>(client_id: ClientId, |
|
|
|
}
|
|
|
|
ServerStateAction::Packet(pkt) => {
|
|
|
|
trace!("[send to {:?}] {:?}", client_id, pkt);
|
|
|
|
send_pkt(socket.clone(), cipher_out.clone(), pkt).await
|
|
|
|
if let Err(err) = send_pkt(socket.clone(), cipher_out.clone(), pkt).await {
|
|
|
|
warn!("[client {:?} send error ] {:?}", client_id, err);
|
|
|
|
}
|
|
|
|
},
|
|
|
|
ServerStateAction::Disconnect => {
|
|
|
|
break;
|
|
|
|