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?
170fn client(authentication: ClientAuthentication) {
171 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
172 udp_socket.set_nonblocking(true).unwrap();
173 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
174 let mut client = NetcodeClient::new(now, authentication).unwrap();
175 let stdin_channel = spawn_stdin_channel();
176 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
177
178 let mut last_updated = Instant::now();
179 loop {
180 if let Some(err) = client.disconnect_reason() {
181 panic!("Client error: {:?}", err);
182 }
183
184 match stdin_channel.try_recv() {
185 Ok(text) => {
186 if client.is_connected() {
187 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
188 udp_socket.send_to(payload, addr).unwrap();
189 } else {
190 println!("Client is not yet connected");
191 }
192 }
193 Err(TryRecvError::Empty) => {}
194 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
195 }
196
197 loop {
198 match udp_socket.recv_from(&mut buffer) {
199 Ok((len, addr)) => {
200 if addr != client.server_addr() {
201 // Ignore packets that are not from the server
202 continue;
203 }
204 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
205 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
206 let text = String::from_utf8(payload.to_vec()).unwrap();
207 println!("Received message from server: {}", text);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
211 Err(e) => panic!("Socket error: {}", e),
212 };
213 }
214
215 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
216 udp_socket.send_to(packet, addr).unwrap();
217 }
218 last_updated = Instant::now();
219 thread::sleep(Duration::from_millis(50));
220 }
221}pub fn is_connecting(&self) -> bool
Sourcepub fn is_connected(&self) -> bool
pub fn is_connected(&self) -> bool
Examples found in repository?
170fn client(authentication: ClientAuthentication) {
171 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
172 udp_socket.set_nonblocking(true).unwrap();
173 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
174 let mut client = NetcodeClient::new(now, authentication).unwrap();
175 let stdin_channel = spawn_stdin_channel();
176 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
177
178 let mut last_updated = Instant::now();
179 loop {
180 if let Some(err) = client.disconnect_reason() {
181 panic!("Client error: {:?}", err);
182 }
183
184 match stdin_channel.try_recv() {
185 Ok(text) => {
186 if client.is_connected() {
187 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
188 udp_socket.send_to(payload, addr).unwrap();
189 } else {
190 println!("Client is not yet connected");
191 }
192 }
193 Err(TryRecvError::Empty) => {}
194 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
195 }
196
197 loop {
198 match udp_socket.recv_from(&mut buffer) {
199 Ok((len, addr)) => {
200 if addr != client.server_addr() {
201 // Ignore packets that are not from the server
202 continue;
203 }
204 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
205 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
206 let text = String::from_utf8(payload.to_vec()).unwrap();
207 println!("Received message from server: {}", text);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
211 Err(e) => panic!("Socket error: {}", e),
212 };
213 }
214
215 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
216 udp_socket.send_to(packet, addr).unwrap();
217 }
218 last_updated = Instant::now();
219 thread::sleep(Duration::from_millis(50));
220 }
221}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?
170fn client(authentication: ClientAuthentication) {
171 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
172 udp_socket.set_nonblocking(true).unwrap();
173 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
174 let mut client = NetcodeClient::new(now, authentication).unwrap();
175 let stdin_channel = spawn_stdin_channel();
176 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
177
178 let mut last_updated = Instant::now();
179 loop {
180 if let Some(err) = client.disconnect_reason() {
181 panic!("Client error: {:?}", err);
182 }
183
184 match stdin_channel.try_recv() {
185 Ok(text) => {
186 if client.is_connected() {
187 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
188 udp_socket.send_to(payload, addr).unwrap();
189 } else {
190 println!("Client is not yet connected");
191 }
192 }
193 Err(TryRecvError::Empty) => {}
194 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
195 }
196
197 loop {
198 match udp_socket.recv_from(&mut buffer) {
199 Ok((len, addr)) => {
200 if addr != client.server_addr() {
201 // Ignore packets that are not from the server
202 continue;
203 }
204 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
205 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
206 let text = String::from_utf8(payload.to_vec()).unwrap();
207 println!("Received message from server: {}", text);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
211 Err(e) => panic!("Socket error: {}", e),
212 };
213 }
214
215 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
216 udp_socket.send_to(packet, addr).unwrap();
217 }
218 last_updated = Instant::now();
219 thread::sleep(Duration::from_millis(50));
220 }
221}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?
170fn client(authentication: ClientAuthentication) {
171 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
172 udp_socket.set_nonblocking(true).unwrap();
173 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
174 let mut client = NetcodeClient::new(now, authentication).unwrap();
175 let stdin_channel = spawn_stdin_channel();
176 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
177
178 let mut last_updated = Instant::now();
179 loop {
180 if let Some(err) = client.disconnect_reason() {
181 panic!("Client error: {:?}", err);
182 }
183
184 match stdin_channel.try_recv() {
185 Ok(text) => {
186 if client.is_connected() {
187 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
188 udp_socket.send_to(payload, addr).unwrap();
189 } else {
190 println!("Client is not yet connected");
191 }
192 }
193 Err(TryRecvError::Empty) => {}
194 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
195 }
196
197 loop {
198 match udp_socket.recv_from(&mut buffer) {
199 Ok((len, addr)) => {
200 if addr != client.server_addr() {
201 // Ignore packets that are not from the server
202 continue;
203 }
204 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
205 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
206 let text = String::from_utf8(payload.to_vec()).unwrap();
207 println!("Received message from server: {}", text);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
211 Err(e) => panic!("Socket error: {}", e),
212 };
213 }
214
215 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
216 udp_socket.send_to(packet, addr).unwrap();
217 }
218 last_updated = Instant::now();
219 thread::sleep(Duration::from_millis(50));
220 }
221}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?
170fn client(authentication: ClientAuthentication) {
171 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
172 udp_socket.set_nonblocking(true).unwrap();
173 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
174 let mut client = NetcodeClient::new(now, authentication).unwrap();
175 let stdin_channel = spawn_stdin_channel();
176 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
177
178 let mut last_updated = Instant::now();
179 loop {
180 if let Some(err) = client.disconnect_reason() {
181 panic!("Client error: {:?}", err);
182 }
183
184 match stdin_channel.try_recv() {
185 Ok(text) => {
186 if client.is_connected() {
187 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
188 udp_socket.send_to(payload, addr).unwrap();
189 } else {
190 println!("Client is not yet connected");
191 }
192 }
193 Err(TryRecvError::Empty) => {}
194 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
195 }
196
197 loop {
198 match udp_socket.recv_from(&mut buffer) {
199 Ok((len, addr)) => {
200 if addr != client.server_addr() {
201 // Ignore packets that are not from the server
202 continue;
203 }
204 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
205 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
206 let text = String::from_utf8(payload.to_vec()).unwrap();
207 println!("Received message from server: {}", text);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
211 Err(e) => panic!("Socket error: {}", e),
212 };
213 }
214
215 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
216 udp_socket.send_to(packet, addr).unwrap();
217 }
218 last_updated = Instant::now();
219 thread::sleep(Duration::from_millis(50));
220 }
221}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?
170fn client(authentication: ClientAuthentication) {
171 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
172 udp_socket.set_nonblocking(true).unwrap();
173 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
174 let mut client = NetcodeClient::new(now, authentication).unwrap();
175 let stdin_channel = spawn_stdin_channel();
176 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
177
178 let mut last_updated = Instant::now();
179 loop {
180 if let Some(err) = client.disconnect_reason() {
181 panic!("Client error: {:?}", err);
182 }
183
184 match stdin_channel.try_recv() {
185 Ok(text) => {
186 if client.is_connected() {
187 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
188 udp_socket.send_to(payload, addr).unwrap();
189 } else {
190 println!("Client is not yet connected");
191 }
192 }
193 Err(TryRecvError::Empty) => {}
194 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
195 }
196
197 loop {
198 match udp_socket.recv_from(&mut buffer) {
199 Ok((len, addr)) => {
200 if addr != client.server_addr() {
201 // Ignore packets that are not from the server
202 continue;
203 }
204 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
205 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
206 let text = String::from_utf8(payload.to_vec()).unwrap();
207 println!("Received message from server: {}", text);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
211 Err(e) => panic!("Socket error: {}", e),
212 };
213 }
214
215 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
216 udp_socket.send_to(packet, addr).unwrap();
217 }
218 last_updated = Instant::now();
219 thread::sleep(Duration::from_millis(50));
220 }
221}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?
170fn client(authentication: ClientAuthentication) {
171 let udp_socket = UdpSocket::bind("127.0.0.1:0").unwrap();
172 udp_socket.set_nonblocking(true).unwrap();
173 let now = SystemTime::now().duration_since(UNIX_EPOCH).unwrap();
174 let mut client = NetcodeClient::new(now, authentication).unwrap();
175 let stdin_channel = spawn_stdin_channel();
176 let mut buffer = [0u8; NETCODE_MAX_PACKET_BYTES];
177
178 let mut last_updated = Instant::now();
179 loop {
180 if let Some(err) = client.disconnect_reason() {
181 panic!("Client error: {:?}", err);
182 }
183
184 match stdin_channel.try_recv() {
185 Ok(text) => {
186 if client.is_connected() {
187 let (addr, payload) = client.generate_payload_packet(text.as_bytes()).unwrap();
188 udp_socket.send_to(payload, addr).unwrap();
189 } else {
190 println!("Client is not yet connected");
191 }
192 }
193 Err(TryRecvError::Empty) => {}
194 Err(TryRecvError::Disconnected) => panic!("Stdin channel disconnected"),
195 }
196
197 loop {
198 match udp_socket.recv_from(&mut buffer) {
199 Ok((len, addr)) => {
200 if addr != client.server_addr() {
201 // Ignore packets that are not from the server
202 continue;
203 }
204 // println!("Received decrypted message {:?} from server {}", &buffer[..len], addr);
205 if let Some(payload) = client.process_packet(&mut buffer[..len]) {
206 let text = String::from_utf8(payload.to_vec()).unwrap();
207 println!("Received message from server: {}", text);
208 }
209 }
210 Err(ref e) if e.kind() == std::io::ErrorKind::WouldBlock => break,
211 Err(e) => panic!("Socket error: {}", e),
212 };
213 }
214
215 if let Some((packet, addr)) = client.update(Instant::now() - last_updated) {
216 udp_socket.send_to(packet, addr).unwrap();
217 }
218 last_updated = Instant::now();
219 thread::sleep(Duration::from_millis(50));
220 }
221}