naia-server 0.25.0

A server that uses either UDP or WebRTC communication to send/receive messages to/from connected clients, and syncs registered Entities/Components to clients to whom they are in-scope.
use std::net::SocketAddr;

use naia_shared::LinkConditionerConfig;

use crate::transport::{
    AuthReceiver as TransportAuthReceiver, AuthSender as TransportAuthSender,
    ConditionedPacketReceiver, ListenResult, PacketReceiver as TransportReceiver,
    PacketSender as TransportSender, RecvError, SendError, Socket as TransportSocket,
};

use super::{
    LocalServerAuthReceiver, LocalServerAuthSender, LocalServerReceiver, LocalServerSender,
    LocalServerSocket,
};

#[doc(hidden)]
pub struct Socket {
    inner: Option<LocalServerSocket>,
    config: Option<LinkConditionerConfig>,
}

impl Socket {
    #[doc(hidden)]
    pub fn new(local: LocalServerSocket, config: Option<LinkConditionerConfig>) -> Self {
        Self {
            inner: Some(local),
            config,
        }
    }
}

impl From<Socket> for Box<dyn TransportSocket> {
    fn from(val: Socket) -> Self {
        Box::new(val)
    }
}

impl TransportSocket for Socket {
    fn listen(self: Box<Self>) -> ListenResult {
        let Socket { inner, config } = *self;
        let local = inner.expect("server socket already taken");
        let (auth_sender, auth_receiver, sender, receiver) = local.listen_with_auth();

        let receiver: Box<dyn TransportReceiver> = {
            let wrapped = LocalServerTransportReceiver(receiver);
            if let Some(config) = &config {
                Box::new(ConditionedPacketReceiver::new(Box::new(wrapped), config))
            } else {
                Box::new(wrapped)
            }
        };

        (
            Box::new(LocalServerTransportAuthSender(auth_sender)),
            Box::new(LocalServerTransportAuthReceiver(auth_receiver)),
            Box::new(LocalServerTransportSender(sender)),
            receiver,
        )
    }
}

#[derive(Clone)]
struct LocalServerTransportSender(LocalServerSender);

impl TransportSender for LocalServerTransportSender {
    fn send(&self, address: &SocketAddr, payload: &[u8]) -> Result<(), SendError> {
        self.0.send(address, payload).map_err(|_| SendError)
    }
}

#[derive(Clone)]
struct LocalServerTransportReceiver(LocalServerReceiver);

impl TransportReceiver for LocalServerTransportReceiver {
    fn receive(&mut self) -> Result<Option<(SocketAddr, &[u8])>, RecvError> {
        self.0.receive().map_err(|_| RecvError)
    }
}

#[derive(Clone)]
struct LocalServerTransportAuthSender(LocalServerAuthSender);

impl TransportAuthSender for LocalServerTransportAuthSender {
    fn accept(
        &self,
        address: &SocketAddr,
        identity_token: &naia_shared::IdentityToken,
    ) -> Result<(), SendError> {
        self.0
            .accept(address, identity_token)
            .map_err(|_| SendError)
    }

    fn reject(&self, address: &SocketAddr) -> Result<(), SendError> {
        self.0.reject(address).map_err(|_| SendError)
    }
}

#[derive(Clone)]
struct LocalServerTransportAuthReceiver(LocalServerAuthReceiver);

impl TransportAuthReceiver for LocalServerTransportAuthReceiver {
    fn receive(&mut self) -> Result<Option<(SocketAddr, &[u8])>, RecvError> {
        self.0.receive().map_err(|_| RecvError)
    }
}