1use renet::{
2 disconnect_packet,
3 error::{DisconnectionReason, RenetError},
4 remote_connection::ConnectionConfig,
5 server::Server,
6};
7
8use log::error;
9use std::{
10 collections::VecDeque,
11 io,
12 net::{SocketAddr, UdpSocket},
13 time::Duration,
14};
15
16#[derive(Debug)]
17pub struct UdpServer {
18 socket: UdpSocket,
19 server: Server<SocketAddr>,
20 buffer: Box<[u8]>,
21 events: VecDeque<ServerEvent>,
22}
23
24#[derive(Debug, Clone)]
25pub enum ServerEvent {
26 ClientConnected(SocketAddr),
27 ClientDisconnected(SocketAddr, DisconnectionReason),
28}
29
30impl UdpServer {
31 pub fn new(max_clients: usize, connection_config: ConnectionConfig, socket: UdpSocket) -> Result<Self, std::io::Error> {
32 let buffer = vec![0u8; connection_config.max_packet_size as usize].into_boxed_slice();
33 let server = Server::new(max_clients, connection_config);
34 socket.set_nonblocking(true)?;
35
36 Ok(Self {
37 socket,
38 server,
39 buffer,
40 events: VecDeque::new(),
41 })
42 }
43
44 pub fn addr(&self) -> Result<SocketAddr, io::Error> {
45 self.socket.local_addr()
46 }
47
48 pub fn get_event(&mut self) -> Option<ServerEvent> {
49 self.events.pop_front()
50 }
51
52 pub fn disconnect(&mut self, client_id: &SocketAddr) {
53 self.server.disconnect(client_id);
54 }
55
56 pub fn disconnect_clients(&mut self) {
57 self.server.disconnect_all();
58 }
59
60 pub fn update(&mut self, duration: Duration) -> Result<(), io::Error> {
61 loop {
62 match self.socket.recv_from(&mut self.buffer) {
63 Ok((len, addr)) => {
64 if !self.server.is_connected(&addr) {
65 match self.server.add_connection(&addr) {
66 Ok(()) => self.events.push_back(ServerEvent::ClientConnected(addr)),
67 Err(reason) => self.send_disconnect_packet(&addr, reason),
68 }
69 }
70 if let Err(e) = self.server.process_packet_from(&self.buffer[..len], &addr) {
71 error!("Error while processing payload for {}: {}", addr, e)
72 }
73 }
74 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
75 Err(e) => return Err(e),
76 };
77 }
78
79 self.server.update_connections(duration);
80 while let Some((client_id, reason)) = self.server.disconnected_client() {
81 self.events.push_back(ServerEvent::ClientDisconnected(client_id, reason));
82 self.send_disconnect_packet(&client_id, reason);
83 }
84 Ok(())
85 }
86
87 fn send_disconnect_packet(&self, addr: &SocketAddr, reason: DisconnectionReason) {
88 if matches!(reason, DisconnectionReason::DisconnectedByClient) {
89 return;
90 }
91 match disconnect_packet(reason) {
92 Ok(packet) => {
93 const NUM_DISCONNECT_PACKETS_TO_SEND: u32 = 5;
94 for _ in 0..NUM_DISCONNECT_PACKETS_TO_SEND {
95 if let Err(e) = self.socket.send_to(&packet, addr) {
96 error!("failed to send disconnect packet to {}: {}", addr, e);
97 }
98 }
99 }
100 Err(e) => {
101 error!("failed to serialize disconnect packet: {}", e);
102 }
103 }
104 }
105
106 pub fn receive_message(&mut self, client: &SocketAddr, channel_id: u8) -> Option<Vec<u8>> {
107 self.server.receive_message(client, channel_id)
108 }
109
110 pub fn send_message(&mut self, client_id: &SocketAddr, channel_id: u8, message: Vec<u8>) -> Result<(), RenetError> {
111 self.server.send_message(client_id, channel_id, message)
112 }
113
114 pub fn broadcast_message_except(&mut self, client_id: &SocketAddr, channel_id: u8, message: Vec<u8>) {
115 self.server.broadcast_message_except(client_id, channel_id, message)
116 }
117
118 pub fn broadcast_message(&mut self, channel_id: u8, message: Vec<u8>) {
119 self.server.broadcast_message(channel_id, message);
120 }
121
122 pub fn send_packets(&mut self) -> Result<(), io::Error> {
123 for client_id in self.server.connections_id().iter() {
124 let packets = match self.server.get_packets_to_send(client_id) {
125 Ok(p) => p,
126 Err(e) => {
127 self.server.disconnect(client_id);
128 error!("Failed to get packets from {}: {}", client_id, e);
129 continue;
130 }
131 };
132
133 for packet in packets.iter() {
134 self.socket.send_to(packet, client_id)?;
135 }
136 }
137 Ok(())
138 }
139
140 pub fn clients_id(&self) -> Vec<SocketAddr> {
141 self.server.connections_id()
142 }
143}