pub struct ChannelServer {
clients: Vec<ChannelConnection>,
received: Vec<DataPacket<1024>>,
}
struct ChannelConnection {
outgoing: Sender<Packets>,
incoming: Receiver<Packets>,
pending_connection_id: Option<u64>,
session: Option<Session>,
}
impl ChannelServer {
pub fn new() -> Self {
Self {
clients: Vec::new(),
received: Vec::new(),
}
}
pub fn client(&mut self) -> ChannelClient {
let (server_to_client, client_incoming) = std::sync::mpsc::channel();
let (client_to_server, server_incoming) = std::sync::mpsc::channel();
self.clients.push(ChannelConnection {
outgoing: server_to_client,
incoming: server_incoming,
pending_connection_id: None,
session: None,
});
ChannelClient::new(client_incoming, client_to_server)
}
pub fn is_connected(&self) -> bool {
self.clients
.iter()
.any(|client| client.session.as_ref().is_some_and(Session::is_connected))
}
pub fn connected_clients(&self) -> usize {
self.clients
.iter()
.filter(|client| client.session.as_ref().is_some_and(Session::is_connected))
.count()
}
pub fn update(&mut self, current_time: Instant) -> Result<Vec<Events>, ConnectionResults> {
let mut events = Vec::new();
for client in &mut self.clients {
let mut packets = Vec::new();
while let Ok(packet) = client.incoming.try_recv() {
packets.push(packet);
}
for packet in &packets {
match packet {
Packets::ConnectionRequest(request) => {
let server_salt = 0x4254_4550;
let connection_id = request.get_client_salt() ^ server_salt;
client.pending_connection_id = Some(connection_id);
client
.outgoing
.send(ChallengePacket::new(request.get_client_salt(), server_salt).into())
.map_err(|_| ConnectionResults::ServerFull)?;
}
Packets::ChallengeResponse(response)
if client.pending_connection_id == Some(response.get_connection_id()) =>
{
let id = response.get_connection_id();
let mut session = Session::new();
session.accept(id, current_time);
client.session = Some(session);
client.pending_connection_id = None;
events.push(Events::ClientConnected { id });
}
Packets::Data(packet) => self.received.push(*packet),
_ => {}
}
}
if let Some(session) = &mut client.session {
for packet in session
.update(&packets, current_time)
.map_err(|_| ConnectionResults::ServerFull)?
{
client.outgoing.send(packet).map_err(|_| ConnectionResults::ServerFull)?;
}
}
}
Ok(events)
}
pub fn send(&mut self, reliable: bool, data: [u8; 1024]) {
for client in &mut self.clients {
if let Some(session) = &mut client.session {
session.send(reliable, data);
}
}
}
pub fn drain_received(&mut self) -> impl Iterator<Item = DataPacket<1024>> + '_ {
self.received.drain(..)
}
pub fn disconnect(&mut self) {
for client in &mut self.clients {
if let Some(session) = &mut client.session {
session.disconnect();
}
}
}
}
impl Default for ChannelServer {
fn default() -> Self {
Self::new()
}
}
use std::{
sync::mpsc::{Receiver, Sender, TryRecvError},
time::Instant,
};
use betp::{
packets::{ChallengePacket, DataPacket, Packets},
server::{ConnectionResults, Events, Session},
};
use crate::network::client::ChannelClient;