>();
- self.add_system(
- receive_server_packets::
- .after(ServerNetworkPlugin::remove_disconnected)
- .before(ServerNetworkPlugin::clear_cache),
- );
- self
- }
-}
-
-/// An event for received [Packet]s on the server.
-pub struct PacketEvent {
- /// The [ClientConnection] from which the [Packet] was received.
- pub connection: ClientConnection,
-
- /// The [Entity] of the [ClientConnection].
- pub entity: Entity,
-
- /// The [Packet]
- pub packet: P,
-}
-
-/// Receives [Packet]s and sends them as [Event]s.
-fn receive_client_packets(
- mut writer: EventWriter,
- connection: Res,
-) {
- for packet in connection.0.recv() {
- writer.send(packet);
- }
-}
-
-/// An extention trait to easily register a [Packet] to the client.
-pub trait AppClientNetwork {
- /// Registers a [Packet] for the client.
- fn register_client_packet(&mut self) -> &mut Self;
-}
-
-impl AppClientNetwork for App {
- fn register_client_packet(&mut self) -> &mut Self {
- self.add_event::();
- self.add_system(
- receive_client_packets::
- .run_if(resource_exists::())
- .after(ClientNetworkPlugin::remove_disconnected)
- .before(ClientNetworkPlugin::clear_cache),
- );
- self
- }
-}
diff --git a/src/packet.rs b/src/packet.rs
deleted file mode 100644
index 7a9a5e0..0000000
--- a/src/packet.rs
+++ /dev/null
@@ -1,57 +0,0 @@
-use dashmap::DashMap;
-use serde::{de::DeserializeOwned, Serialize};
-
-/// A [Packet] that can be sent over the network.
-pub trait Packet: DeserializeOwned + Serialize + Sync + Send + 'static {
- const ID: u32;
-}
-
-/// A macro to easily implement [Packet].
-#[macro_export]
-macro_rules! impl_packet {
- ($t:ty) => {
- impl ::bevnet::Packet for $t {
- const ID: u32 = ::const_fnv1a_hash::fnv1a_hash_32(
- concat!(module_path!(), "::", stringify!($t)).as_bytes(),
- None,
- );
- }
- };
-}
-
-/// A container for the received [Packet]s.
-pub struct PacketReceiver {
- /// The received data.
- data: DashMap>>,
-}
-
-impl PacketReceiver {
- /// Creates a new [PacketReceiver].
- pub fn new() -> Self {
- Self {
- data: DashMap::new(),
- }
- }
-
- /// Clears all the [Packet]s.
- pub fn clear(&self) {
- self.data.clear();
- }
-
- /// Inserts a the received raw [Packet] into the [PacketReceiver].
- pub fn insert(&self, id: u32, data: Vec) {
- self.data.entry(id).or_default().push(data);
- }
-
- /// Extract all the [Packet]s of a given type.
- pub fn extract(&self) -> Vec {
- match self.data.get_mut(&P::ID) {
- Some(mut data) => data
- .value_mut()
- .drain(..)
- .filter_map(|data| bincode::deserialize(&data).ok())
- .collect(),
- None => Vec::new(),
- }
- }
-}
diff --git a/src/tcp.rs b/src/tcp.rs
deleted file mode 100644
index 092d562..0000000
--- a/src/tcp.rs
+++ /dev/null
@@ -1,233 +0,0 @@
-use crate::packet::{Packet, PacketReceiver};
-use std::{
- io::{self, Read, Write},
- net::{Shutdown, SocketAddr, TcpListener, TcpStream, ToSocketAddrs},
- sync::{
- atomic::{AtomicBool, Ordering},
- mpsc::{channel, Receiver, Sender},
- Arc, Mutex,
- },
- thread,
-};
-
-/// Used to send [Packet] to the sending thread.
-type ConnectionSender = Arc)>>>;
-
-/// A TCP [Connection] that can send and receive [Packet].
-pub struct Connection {
- /// Whether or not the [Connection] is currently connected.
- connected: Arc,
-
- /// Used to store the received [Packet]s.
- packets: Arc,
-
- /// Used to send [Packet] to the sending thread.
- sender: ConnectionSender,
-
- /// The [TcpStream] of the [Connection].
- stream: TcpStream,
-
- /// The address of the [Connection].
- address: SocketAddr,
-}
-
-impl Connection {
- /// Creates a new [Connection] with the given [TcpStream].
- pub fn new(stream: TcpStream) -> io::Result {
- let connected = Arc::new(AtomicBool::new(true));
- let packets = Arc::new(PacketReceiver::new());
-
- // Receiving part
- let mut thread_stream = stream.try_clone()?;
- let thread_packets = Arc::clone(&packets);
- let thread_connected = Arc::clone(&connected);
- thread::spawn(move || {
- let mut int_buffer = [0; 4];
-
- loop {
- // Check if the connection is closed
- if !thread_connected.load(Ordering::Relaxed) {
- return;
- }
-
- // Read the length of the packet
- if thread_stream.read_exact(&mut int_buffer).is_err() {
- break;
- }
- let len = u32::from_be_bytes(int_buffer);
-
- // Read the packet identifier
- if thread_stream.read_exact(&mut int_buffer).is_err() {
- break;
- }
- let id = u32::from_be_bytes(int_buffer);
-
- // Read the packet
- let mut buffer = vec![0; len as usize];
- if thread_stream.read_exact(&mut buffer).is_err() {
- break;
- }
-
- // Insert the packet
- thread_packets.insert(id, buffer);
- }
-
- // Close the connection
- thread_connected.store(false, Ordering::Relaxed);
- });
-
- // Sending part
- let mut thread_stream = stream.try_clone()?;
- let (sender, receiver) = channel();
- let thread_connected = Arc::clone(&connected);
- thread::spawn(move || {
- loop {
- // Check if the connection is closed
- if !thread_connected.load(Ordering::Relaxed) {
- return;
- }
-
- // Get the data to send
- let (id, buffer): (u32, Vec) = match receiver.recv() {
- Ok(data) => data,
- Err(_) => break,
- };
-
- // Send the length of the data
- let len = buffer.len() as u32;
- if thread_stream.write_all(&len.to_be_bytes()).is_err() {
- break;
- }
-
- // Send the packet identifier
- if thread_stream.write_all(&id.to_be_bytes()).is_err() {
- break;
- }
-
- // Send the data
- if thread_stream.write_all(&buffer).is_err() {
- break;
- }
-
- // Flush the stream
- if thread_stream.flush().is_err() {
- break;
- }
- }
-
- // Close the connection
- thread_connected.store(false, Ordering::Relaxed);
- });
-
- Ok(Self {
- connected,
- packets,
- sender: Arc::new(Mutex::new(sender)),
- address: stream.peer_addr()?,
- stream,
- })
- }
-
- /// Creates a [Connection] to the given address.
- pub fn connect(address: A) -> io::Result {
- Self::new(TcpStream::connect(address)?)
- }
-
- /// Returns whether or not the [Connection] is currently connected.
- pub fn connected(&self) -> bool {
- self.connected.load(Ordering::Relaxed)
- }
-
- /// Clears the [Packet] cache.
- pub fn clear(&self) {
- self.packets.clear();
- }
-
- /// Gets all the received [Packet]s of a certain type.
- pub fn recv(&self) -> Vec {
- self.packets.extract()
- }
-
- /// Sends the given [Packet] to the [Connection].
- /// Does nothing if the [Connection] is closed.
- pub fn send(&self, packet: P) {
- let data = bincode::serialize(&packet).expect("Failed to serialize packet");
- self.sender
- .lock()
- .map(|sender| sender.send((P::ID, data)))
- .ok();
- }
-
- /// Returns the address of the [Connection].
- pub fn address(&self) -> SocketAddr {
- self.address
- }
-}
-
-impl Drop for Connection {
- fn drop(&mut self) {
- self.connected.store(false, Ordering::Relaxed);
- self.stream.shutdown(Shutdown::Both).ok();
- }
-}
-
-/// A TCP [Listener] that can accept [Connection]s.
-pub struct Listener {
- /// Whether the [Listener] is listening.
- listening: Arc,
-
- /// The receiving part of the [Listener].
- receiver: Arc>>,
-
- /// The address the [Listener] is bound to.
- address: SocketAddr,
-}
-
-impl Listener {
- /// Creates a new [Listener] binded to the given address.
- pub fn bind(address: A) -> io::Result {
- let listener = TcpListener::bind(address)?;
- let address = listener.local_addr()?;
- let listening = Arc::new(AtomicBool::new(true));
- let listening_thread = Arc::clone(&listening);
- let (sender, receiver) = channel();
- thread::spawn(move || {
- for stream in listener.incoming() {
- let connection = match stream {
- Ok(stream) => match Connection::new(stream) {
- Ok(connection) => connection,
- Err(_) => break,
- },
- Err(_) => break,
- };
- if sender.send(connection).is_err() {
- break;
- }
- }
- listening_thread.store(false, Ordering::Relaxed);
- });
- Ok(Self {
- listening,
- receiver: Arc::new(Mutex::new(receiver)),
- address,
- })
- }
-
- /// Returns whether or not the [Listener] is listening.
- pub fn listening(&self) -> bool {
- self.listening.load(Ordering::Relaxed)
- }
-
- /// Receives the next [Connection] from the [Listener].
- pub fn accept(&self) -> Option {
- self.receiver
- .lock()
- .ok()
- .and_then(|receiver| receiver.try_recv().ok())
- }
-
- /// Returns the address the [Listener] is bound to.
- pub fn address(&self) -> SocketAddr {
- self.address
- }
-}