1use std::{
2 io,
3 net::{SocketAddr, UdpSocket},
4 time::Duration,
5};
6
7use renetcode::{NetcodeServer, ServerConfig, ServerResult, NETCODE_MAX_PACKET_BYTES, NETCODE_USER_DATA_BYTES};
8
9use renet::ClientId;
10use renet::RenetServer;
11
12use super::NetcodeTransportError;
13
14#[derive(Debug)]
15pub struct NetcodeServerTransport {
16 socket: UdpSocket,
17 netcode_server: NetcodeServer,
18 buffer: [u8; NETCODE_MAX_PACKET_BYTES],
19}
20
21impl NetcodeServerTransport {
22 pub fn new(server_config: ServerConfig, socket: UdpSocket) -> Result<Self, std::io::Error> {
23 socket.set_nonblocking(true)?;
24
25 let netcode_server = NetcodeServer::new(server_config);
26
27 Ok(Self {
28 socket,
29 netcode_server,
30 buffer: [0; NETCODE_MAX_PACKET_BYTES],
31 })
32 }
33
34 pub fn addresses(&self) -> Vec<SocketAddr> {
36 self.netcode_server.addresses()
37 }
38
39 pub fn max_clients(&self) -> usize {
41 self.netcode_server.max_clients()
42 }
43
44 pub fn set_max_clients(&mut self, max_clients: usize) {
50 self.netcode_server.set_max_clients(max_clients);
51 }
52
53 pub fn connected_clients(&self) -> usize {
55 self.netcode_server.connected_clients()
56 }
57
58 pub fn user_data(&self, client_id: ClientId) -> Option<[u8; NETCODE_USER_DATA_BYTES]> {
60 self.netcode_server.user_data(client_id)
61 }
62
63 pub fn client_addr(&self, client_id: ClientId) -> Option<SocketAddr> {
65 self.netcode_server.client_addr(client_id)
66 }
67
68 pub fn disconnect_all(&mut self, server: &mut RenetServer) {
72 for client_id in self.netcode_server.clients_id() {
73 let server_result = self.netcode_server.disconnect(client_id);
74 handle_server_result(server_result, &self.socket, server);
75 }
76 }
77
78 pub fn time_since_last_received_packet(&self, client_id: ClientId) -> Option<Duration> {
81 self.netcode_server.time_since_last_received_packet(client_id)
82 }
83
84 pub fn update(&mut self, duration: Duration, server: &mut RenetServer) -> Result<(), NetcodeTransportError> {
86 self.netcode_server.update(duration);
87
88 loop {
89 match self.socket.recv_from(&mut self.buffer) {
90 Ok((len, addr)) => {
91 let server_result = self.netcode_server.process_packet(addr, &mut self.buffer[..len]);
92 handle_server_result(server_result, &self.socket, server);
93 }
94 Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => break,
95 Err(ref e) if e.kind() == io::ErrorKind::Interrupted => break,
96 Err(ref e) if e.kind() == io::ErrorKind::ConnectionReset => continue,
97 Err(e) => return Err(e.into()),
98 };
99 }
100
101 for client_id in self.netcode_server.clients_id() {
102 let server_result = self.netcode_server.update_client(client_id);
103 handle_server_result(server_result, &self.socket, server);
104 }
105
106 for disconnection_id in server.disconnections_id() {
107 let server_result = self.netcode_server.disconnect(disconnection_id);
108 handle_server_result(server_result, &self.socket, server);
109 }
110
111 Ok(())
112 }
113
114 pub fn send_packets(&mut self, server: &mut RenetServer) {
116 'clients: for client_id in server.clients_id() {
117 let packets = server.get_packets_to_send(client_id).unwrap();
118 for packet in packets {
119 match self.netcode_server.generate_payload_packet(client_id, &packet) {
120 Ok((addr, payload)) => {
121 if let Err(e) = self.socket.send_to(payload, addr) {
122 log::error!("Failed to send packet to client {client_id} ({addr}): {e}");
123 continue 'clients;
124 }
125 }
126 Err(e) => {
127 log::error!("Failed to encrypt payload packet for client {client_id}: {e}");
128 continue 'clients;
129 }
130 }
131 }
132 }
133 }
134}
135
136fn handle_server_result(server_result: ServerResult, socket: &UdpSocket, reliable_server: &mut RenetServer) {
137 let send_packet = |packet: &[u8], addr: SocketAddr| {
138 if let Err(err) = socket.send_to(packet, addr) {
139 log::error!("Failed to send packet to {addr}: {err}");
140 }
141 };
142
143 match server_result {
144 ServerResult::None => {}
145 ServerResult::PacketToSend { payload, addr } => {
146 send_packet(payload, addr);
147 }
148 ServerResult::Payload { client_id, payload } => {
149 if let Err(e) = reliable_server.process_packet_from(payload, client_id) {
150 log::error!("Error while processing payload for {}: {}", client_id, e);
151 }
152 }
153 ServerResult::ClientConnected {
154 client_id,
155 user_data: _,
156 addr,
157 payload,
158 } => {
159 reliable_server.add_connection(client_id);
160 send_packet(payload, addr);
161 }
162 ServerResult::ClientDisconnected { client_id, addr, payload } => {
163 reliable_server.remove_connection(client_id);
164 if let Some(payload) = payload {
165 send_packet(payload, addr);
166 }
167 }
168 }
169}