pub struct NetcodeClient { /* private fields */ }Expand description
A client that can generate encrypted packets that be sent to the connected server, or consume encrypted packets from the server. The client is agnostic from the transport layer, only consuming and generating bytes that can be transported in any way desired.
Implementations§
Source§impl NetcodeClient
impl NetcodeClient
Sourcepub fn new(
current_time: Duration,
authentication: ClientAuthentication,
) -> Result<Self, NetcodeError>
pub fn new( current_time: Duration, authentication: ClientAuthentication, ) -> Result<Self, NetcodeError>
Examples found in repository?
177fn client(authentication: ClientAuthentication) {
178 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
179 udp_socket.set_nonblocking(true).unwrap();
180 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
181 let mut client = NetcodeClient::new(now, authentication).unwrap();
182 let stdin_channel = spawn_stdin_channel();
183 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
184
185 let mut last_updated = Instant::now();
186 loop {
187 if let Some(err) = client.disconnect_reason() {
188 panic!("Client error: {:?}", err);
189 }
190
191 match stdin_channel.try_recv() {
192 Ok(text) => {
193 if client.is_connected() {
194 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
195 udp_socket.send_to(payload, addr).unwrap();
196 } else {
197 println!("Client is not yet connected");
198 }
199 }
200 Err(TryRecvError::Empty) => {}
201 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
202 }
203
204 loop {
205 match udp_socket.recv_from(&mut buffer) {
206 Ok((len, addr)) => {
207 if addr != client.server_addr() {
208 // Ignore packets that are not from the server
209 continue;
210 }
211 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
212 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
213 let text = String::from_utf8(payload.to_vec()).unwrap();
214 println!("Received message from server: {}", text);
215 }
216 }
217 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
218 Err(e) => panic!("Socket error: {}", e),
219 };
220 }
221
222 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
223 udp_socket.send_to(packet, addr).unwrap();
224 }
225 last_updated = Instant::now();
226 thread::sleep(Duration::from_millis(50));
227 }
228}Sourcepub fn set_encryption_policy(self, policy: bool) -> Self
pub fn set_encryption_policy(self, policy: bool) -> Self
Sets the clients’s encryption policy.
Packets will not be encrypted nor decrypted if set to false.
pub fn is_connecting(&self) -> bool
Sourcepub fn is_connected(&self) -> bool
pub fn is_connected(&self) -> bool
Examples found in repository?
177fn client(authentication: ClientAuthentication) {
178 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
179 udp_socket.set_nonblocking(true).unwrap();
180 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
181 let mut client = NetcodeClient::new(now, authentication).unwrap();
182 let stdin_channel = spawn_stdin_channel();
183 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
184
185 let mut last_updated = Instant::now();
186 loop {
187 if let Some(err) = client.disconnect_reason() {
188 panic!("Client error: {:?}", err);
189 }
190
191 match stdin_channel.try_recv() {
192 Ok(text) => {
193 if client.is_connected() {
194 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
195 udp_socket.send_to(payload, addr).unwrap();
196 } else {
197 println!("Client is not yet connected");
198 }
199 }
200 Err(TryRecvError::Empty) => {}
201 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
202 }
203
204 loop {
205 match udp_socket.recv_from(&mut buffer) {
206 Ok((len, addr)) => {
207 if addr != client.server_addr() {
208 // Ignore packets that are not from the server
209 continue;
210 }
211 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
212 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
213 let text = String::from_utf8(payload.to_vec()).unwrap();
214 println!("Received message from server: {}", text);
215 }
216 }
217 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
218 Err(e) => panic!("Socket error: {}", e),
219 };
220 }
221
222 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
223 udp_socket.send_to(packet, addr).unwrap();
224 }
225 last_updated = Instant::now();
226 thread::sleep(Duration::from_millis(50));
227 }
228}pub fn is_disconnected(&self) -> bool
pub fn current_time(&self) -> Duration
pub fn client_id(&self) -> u64
Sourcepub fn time_since_last_received_packet(&self) -> Duration
pub fn time_since_last_received_packet(&self) -> Duration
Returns the duration since the client last received a packet. Usefull to detect timeouts.
Sourcepub fn disconnect_reason(&self) -> Option<DisconnectReason>
pub fn disconnect_reason(&self) -> Option<DisconnectReason>
Returns the reason that the client was disconnected for.
Examples found in repository?
177fn client(authentication: ClientAuthentication) {
178 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
179 udp_socket.set_nonblocking(true).unwrap();
180 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
181 let mut client = NetcodeClient::new(now, authentication).unwrap();
182 let stdin_channel = spawn_stdin_channel();
183 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
184
185 let mut last_updated = Instant::now();
186 loop {
187 if let Some(err) = client.disconnect_reason() {
188 panic!("Client error: {:?}", err);
189 }
190
191 match stdin_channel.try_recv() {
192 Ok(text) => {
193 if client.is_connected() {
194 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
195 udp_socket.send_to(payload, addr).unwrap();
196 } else {
197 println!("Client is not yet connected");
198 }
199 }
200 Err(TryRecvError::Empty) => {}
201 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
202 }
203
204 loop {
205 match udp_socket.recv_from(&mut buffer) {
206 Ok((len, addr)) => {
207 if addr != client.server_addr() {
208 // Ignore packets that are not from the server
209 continue;
210 }
211 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
212 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
213 let text = String::from_utf8(payload.to_vec()).unwrap();
214 println!("Received message from server: {}", text);
215 }
216 }
217 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
218 Err(e) => panic!("Socket error: {}", e),
219 };
220 }
221
222 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
223 udp_socket.send_to(packet, addr).unwrap();
224 }
225 last_updated = Instant::now();
226 thread::sleep(Duration::from_millis(50));
227 }
228}Sourcepub fn server_addr(&self) -> SocketAddr
pub fn server_addr(&self) -> SocketAddr
Returns the current server address the client is connected or trying to connect.
Examples found in repository?
177fn client(authentication: ClientAuthentication) {
178 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
179 udp_socket.set_nonblocking(true).unwrap();
180 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
181 let mut client = NetcodeClient::new(now, authentication).unwrap();
182 let stdin_channel = spawn_stdin_channel();
183 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
184
185 let mut last_updated = Instant::now();
186 loop {
187 if let Some(err) = client.disconnect_reason() {
188 panic!("Client error: {:?}", err);
189 }
190
191 match stdin_channel.try_recv() {
192 Ok(text) => {
193 if client.is_connected() {
194 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
195 udp_socket.send_to(payload, addr).unwrap();
196 } else {
197 println!("Client is not yet connected");
198 }
199 }
200 Err(TryRecvError::Empty) => {}
201 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
202 }
203
204 loop {
205 match udp_socket.recv_from(&mut buffer) {
206 Ok((len, addr)) => {
207 if addr != client.server_addr() {
208 // Ignore packets that are not from the server
209 continue;
210 }
211 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
212 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
213 let text = String::from_utf8(payload.to_vec()).unwrap();
214 println!("Received message from server: {}", text);
215 }
216 }
217 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
218 Err(e) => panic!("Socket error: {}", e),
219 };
220 }
221
222 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
223 udp_socket.send_to(packet, addr).unwrap();
224 }
225 last_updated = Instant::now();
226 thread::sleep(Duration::from_millis(50));
227 }
228}Sourcepub fn disconnect(&mut self) -> Result<(SocketAddr, &mut [u8]), NetcodeError>
pub fn disconnect(&mut self) -> Result<(SocketAddr, &mut [u8]), NetcodeError>
Disconnect the client from the server. Returns a disconnect packet that should be sent to the server.
Sourcepub fn process_packet<'a>(&mut self, buffer: &'a mut [u8]) -> Option<&'a [u8]>
pub fn process_packet<'a>(&mut self, buffer: &'a mut [u8]) -> Option<&'a [u8]>
Process any packet received from the server. This function might return a payload sent from the server. If nothing is returned, it was a packet used for the internal protocol or an invalid packet.
Examples found in repository?
177fn client(authentication: ClientAuthentication) {
178 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
179 udp_socket.set_nonblocking(true).unwrap();
180 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
181 let mut client = NetcodeClient::new(now, authentication).unwrap();
182 let stdin_channel = spawn_stdin_channel();
183 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
184
185 let mut last_updated = Instant::now();
186 loop {
187 if let Some(err) = client.disconnect_reason() {
188 panic!("Client error: {:?}", err);
189 }
190
191 match stdin_channel.try_recv() {
192 Ok(text) => {
193 if client.is_connected() {
194 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
195 udp_socket.send_to(payload, addr).unwrap();
196 } else {
197 println!("Client is not yet connected");
198 }
199 }
200 Err(TryRecvError::Empty) => {}
201 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
202 }
203
204 loop {
205 match udp_socket.recv_from(&mut buffer) {
206 Ok((len, addr)) => {
207 if addr != client.server_addr() {
208 // Ignore packets that are not from the server
209 continue;
210 }
211 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
212 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
213 let text = String::from_utf8(payload.to_vec()).unwrap();
214 println!("Received message from server: {}", text);
215 }
216 }
217 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
218 Err(e) => panic!("Socket error: {}", e),
219 };
220 }
221
222 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
223 udp_socket.send_to(packet, addr).unwrap();
224 }
225 last_updated = Instant::now();
226 thread::sleep(Duration::from_millis(50));
227 }
228}Sourcepub fn generate_payload_packet(
&mut self,
payload: &[u8],
) -> Result<(SocketAddr, &mut [u8]), NetcodeError>
pub fn generate_payload_packet( &mut self, payload: &[u8], ) -> Result<(SocketAddr, &mut [u8]), NetcodeError>
Returns the server address and an encrypted payload packet that can be sent to the server.
Examples found in repository?
177fn client(authentication: ClientAuthentication) {
178 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
179 udp_socket.set_nonblocking(true).unwrap();
180 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
181 let mut client = NetcodeClient::new(now, authentication).unwrap();
182 let stdin_channel = spawn_stdin_channel();
183 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
184
185 let mut last_updated = Instant::now();
186 loop {
187 if let Some(err) = client.disconnect_reason() {
188 panic!("Client error: {:?}", err);
189 }
190
191 match stdin_channel.try_recv() {
192 Ok(text) => {
193 if client.is_connected() {
194 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
195 udp_socket.send_to(payload, addr).unwrap();
196 } else {
197 println!("Client is not yet connected");
198 }
199 }
200 Err(TryRecvError::Empty) => {}
201 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
202 }
203
204 loop {
205 match udp_socket.recv_from(&mut buffer) {
206 Ok((len, addr)) => {
207 if addr != client.server_addr() {
208 // Ignore packets that are not from the server
209 continue;
210 }
211 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
212 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
213 let text = String::from_utf8(payload.to_vec()).unwrap();
214 println!("Received message from server: {}", text);
215 }
216 }
217 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
218 Err(e) => panic!("Socket error: {}", e),
219 };
220 }
221
222 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
223 udp_socket.send_to(packet, addr).unwrap();
224 }
225 last_updated = Instant::now();
226 thread::sleep(Duration::from_millis(50));
227 }
228}Sourcepub fn update(&mut self, duration: Duration) -> Option<(&mut [u8], SocketAddr)>
pub fn update(&mut self, duration: Duration) -> Option<(&mut [u8], SocketAddr)>
Update the internal state of the client, receives the duration since last updated. Might return the serve address and a protocol packet to be sent to the server.
Examples found in repository?
177fn client(authentication: ClientAuthentication) {
178 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
179 udp_socket.set_nonblocking(true).unwrap();
180 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
181 let mut client = NetcodeClient::new(now, authentication).unwrap();
182 let stdin_channel = spawn_stdin_channel();
183 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
184
185 let mut last_updated = Instant::now();
186 loop {
187 if let Some(err) = client.disconnect_reason() {
188 panic!("Client error: {:?}", err);
189 }
190
191 match stdin_channel.try_recv() {
192 Ok(text) => {
193 if client.is_connected() {
194 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
195 udp_socket.send_to(payload, addr).unwrap();
196 } else {
197 println!("Client is not yet connected");
198 }
199 }
200 Err(TryRecvError::Empty) => {}
201 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
202 }
203
204 loop {
205 match udp_socket.recv_from(&mut buffer) {
206 Ok((len, addr)) => {
207 if addr != client.server_addr() {
208 // Ignore packets that are not from the server
209 continue;
210 }
211 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
212 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
213 let text = String::from_utf8(payload.to_vec()).unwrap();
214 println!("Received message from server: {}", text);
215 }
216 }
217 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
218 Err(e) => panic!("Socket error: {}", e),
219 };
220 }
221
222 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
223 udp_socket.send_to(packet, addr).unwrap();
224 }
225 last_updated = Instant::now();
226 thread::sleep(Duration::from_millis(50));
227 }
228}