From 9050cb85f3d1d4a69276e0e678b51a22f56c06c1 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 11 Jan 2024 20:11:58 -0600 Subject: [PATCH 01/99] - expose various naia_shared types to naia_client library - naia_client_socket packet senders now have `is_connected()` & `disconnect()` methods --- client/src/lib.rs | 2 +- .../src/backends/miniquad/naia_socket.js | 16 +++++++++++ .../src/backends/miniquad/packet_sender.rs | 14 +++++++++- socket/client/src/backends/miniquad/shared.rs | 2 ++ .../src/backends/native/packet_sender.rs | 14 ++++++++-- socket/client/src/backends/native/socket.rs | 2 +- .../backends/wasm_bindgen/packet_sender.rs | 27 +++++++++++++++---- socket/client/src/packet_sender.rs | 4 +++ 8 files changed, 71 insertions(+), 10 deletions(-) diff --git a/client/src/lib.rs b/client/src/lib.rs index 7a6a9f3b7..34adf2bb4 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -16,7 +16,7 @@ extern crate cfg_if; pub mod transport; pub mod shared { pub use naia_shared::{ - default_channels, sequence_greater_than, Instant, Random, SocketConfig, Tick, + default_channels, sequence_greater_than, Instant, Random, SocketConfig, Tick, Message, Protocol, }; } pub mod internal { diff --git a/socket/client/src/backends/miniquad/naia_socket.js b/socket/client/src/backends/miniquad/naia_socket.js index 6bbd8ee01..e1dc5eba0 100644 --- a/socket/client/src/backends/miniquad/naia_socket.js +++ b/socket/client/src/backends/miniquad/naia_socket.js @@ -6,7 +6,9 @@ const naia_socket = { unique_js_id: 0, plugin: function (importObject) { + importObject.env.naia_is_connected = function () { return naia_socket.is_connected(); }; importObject.env.naia_connect = function (address, rtc_path) { naia_socket.connect(address, rtc_path); }; + importObject.env.naia_disconnect = function () { naia_socket.disconnect(); }; importObject.env.naia_send = function (message) { return naia_socket.send(message); }; importObject.env.naia_create_string = function (buf, max_len) { return naia_socket.js_create_string(buf, max_len); }; importObject.env.naia_unwrap_to_str = function (js_object, buf, max_len) { naia_socket.js_unwrap_to_str(js_object, buf, max_len); }; @@ -19,6 +21,14 @@ const naia_socket = { importObject.env.naia_now = function () { return Date.now(); }; }, + is_connected: function() { + if (this.channel) { + return true; + } else { + return false; + } + }, + connect: function (server_socket_address, rtc_path) { let server_socket_address_string = naia_socket.get_js_object(server_socket_address); let rtc_path_string = naia_socket.get_js_object(rtc_path); @@ -91,6 +101,12 @@ const naia_socket = { }); }, + disconnect: function() { + if (this.channel) { + this.channel = null; + } + }, + error: function (desc, err) { err['naia_desc'] = desc; wasm_exports.error(this.js_object(JSON.stringify(err))); diff --git a/socket/client/src/backends/miniquad/packet_sender.rs b/socket/client/src/backends/miniquad/packet_sender.rs index 9178ba0ce..15ed37259 100644 --- a/socket/client/src/backends/miniquad/packet_sender.rs +++ b/socket/client/src/backends/miniquad/packet_sender.rs @@ -1,6 +1,6 @@ use crate::{error::NaiaClientSocketError, packet_sender::PacketSender, ServerAddr}; -use super::shared::{naia_create_u8_array, naia_send, SERVER_ADDR}; +use super::shared::{naia_create_u8_array, naia_send, naia_disconnect, naia_is_connected, SERVER_ADDR}; /// Handles sending messages to the Server for a given Client Socket #[derive(Clone, Default)] @@ -25,4 +25,16 @@ impl PacketSender for PacketSenderImpl { fn server_addr(&self) -> ServerAddr { unsafe { SERVER_ADDR } } + + fn connected(&self) -> bool { + unsafe { + return naia_is_connected(); + } + } + + fn disconnect(&mut self) { + unsafe { + naia_disconnect(); + } + } } diff --git a/socket/client/src/backends/miniquad/shared.rs b/socket/client/src/backends/miniquad/shared.rs index 96fe38676..bdcb998b2 100644 --- a/socket/client/src/backends/miniquad/shared.rs +++ b/socket/client/src/backends/miniquad/shared.rs @@ -18,7 +18,9 @@ pub static mut SERVER_ADDR: ServerAddr = ServerAddr::Finding; // Javascript methods extern "C" { + pub fn naia_is_connected() -> bool; pub fn naia_connect(server_socket_address: JsObject, rtc_path: JsObject); + pub fn naia_disconnect(); pub fn naia_send(message: JsObject) -> bool; pub fn naia_free_object(js_object: JsObjectWeak); pub fn naia_create_string(buf: *const u8, max_len: u32) -> JsObject; diff --git a/socket/client/src/backends/native/packet_sender.rs b/socket/client/src/backends/native/packet_sender.rs index ade6f3fe4..ecda10067 100644 --- a/socket/client/src/backends/native/packet_sender.rs +++ b/socket/client/src/backends/native/packet_sender.rs @@ -1,4 +1,4 @@ -use tokio::sync::mpsc::{error::SendError, UnboundedSender}; +use tokio::sync::{mpsc::{Sender, error::SendError, UnboundedSender}}; use webrtc_unreliable_client::{AddrCell, ServerAddr as RTCServerAddr}; use crate::{error::NaiaClientSocketError, packet_sender::PacketSender, server_addr::ServerAddr}; @@ -8,15 +8,17 @@ use crate::{error::NaiaClientSocketError, packet_sender::PacketSender, server_ad pub struct PacketSenderImpl { server_addr: AddrCell, sender_channel: UnboundedSender>, + disconnect_channel: Sender<()> } impl PacketSenderImpl { /// Create a new PacketSender, if supplied with the Server's address & a /// reference back to the parent Socket - pub fn new(server_addr: AddrCell, sender_channel: UnboundedSender>) -> Self { + pub fn new(server_addr: AddrCell, sender_channel: UnboundedSender>, disconnect_channel: Sender<()>) -> Self { PacketSenderImpl { server_addr, sender_channel, + disconnect_channel } } } @@ -36,4 +38,12 @@ impl PacketSender for PacketSenderImpl { RTCServerAddr::Found(addr) => ServerAddr::Found(addr), } } + + fn connected(&self) -> bool { + !self.sender_channel.is_closed() + } + + fn disconnect(&mut self) { + let _ = self.disconnect_channel.blocking_send(()); + } } diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 82042f585..768d9747c 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -32,7 +32,7 @@ impl Socket { get_runtime().spawn(async move { socket.connect(&server_session_string).await }); // Setup Packet Sender - let packet_sender_impl = PacketSenderImpl::new(io.addr_cell.clone(), io.to_server_sender); + let packet_sender_impl = PacketSenderImpl::new(io.addr_cell.clone(), io.to_server_sender, io.to_server_disconnect_sender); let packet_sender: Box = Box::new(packet_sender_impl); // Setup Packet Receiver diff --git a/socket/client/src/backends/wasm_bindgen/packet_sender.rs b/socket/client/src/backends/wasm_bindgen/packet_sender.rs index 123d5997b..edc9c30e1 100644 --- a/socket/client/src/backends/wasm_bindgen/packet_sender.rs +++ b/socket/client/src/backends/wasm_bindgen/packet_sender.rs @@ -10,6 +10,7 @@ use super::{addr_cell::AddrCell, data_port::DataPort}; pub struct PacketSenderImpl { message_port: MessagePort, server_addr: AddrCell, + connected: bool, } impl PacketSenderImpl { @@ -18,6 +19,7 @@ impl PacketSenderImpl { PacketSenderImpl { message_port: data_port.message_port(), server_addr: addr_cell.clone(), + connected: true, } } } @@ -25,17 +27,32 @@ impl PacketSenderImpl { impl PacketSender for PacketSenderImpl { /// Send a Packet to the Server fn send(&self, payload: &[u8]) -> Result<(), NaiaClientSocketError> { - let uarray: Uint8Array = payload.into(); - self.message_port - .post_message(&uarray) - .expect("Failed to send message"); - Ok(()) + if self.connected { + let uarray: Uint8Array = payload.into(); + self.message_port + .post_message(&uarray) + .expect("Failed to send message"); + Ok(()) + } else { + Err(NaiaClientSocketError::SendError) + } } /// Get the Server's Socket address fn server_addr(&self) -> ServerAddr { self.server_addr.get() } + + fn connected(&self) -> bool { + self.connected + } + + fn disconnect(&mut self) { + if self.connected { + self.connected = false; + self.message_port.close(); + } + } } unsafe impl Send for PacketSenderImpl {} diff --git a/socket/client/src/packet_sender.rs b/socket/client/src/packet_sender.rs index ad1a1963b..0de64c945 100644 --- a/socket/client/src/packet_sender.rs +++ b/socket/client/src/packet_sender.rs @@ -6,6 +6,10 @@ pub trait PacketSender: PacketSenderClone + Send + Sync { fn send(&self, payload: &[u8]) -> Result<(), NaiaClientSocketError>; /// Get the Server's Socket address fn server_addr(&self) -> ServerAddr; + /// Get whether the Client Socket is connected + fn connected(&self) -> bool; + /// Disconnect the Client Socket + fn disconnect(&mut self); } /// Used to clone Box From 29692c50554a384155aa9be7249fc3b8b70b52a6 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 12 Jan 2024 15:15:34 -0600 Subject: [PATCH 02/99] - properly reset client state on disconnection - server checks connection state of user before returning key in `server.user_keys()` --- client/src/client.rs | 6 ++++++ server/src/server.rs | 6 ++++-- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 084c2e95d..35f36495b 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1123,6 +1123,12 @@ impl Client { self.client_config.ping_interval, self.client_config.handshake_pings, ); + + self.manual_disconnect = false; + self.waitlist_messages = VecDeque::new(); + self.global_world_manager = GlobalWorldManager::new(); + self.incoming_events = Events::new(); + self.queued_entity_auth_release_messages = Vec::new(); } fn server_address_unwrapped(&self) -> SocketAddr { diff --git a/server/src/server.rs b/server/src/server.rs index e55630aa3..2334b5374 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -733,8 +733,10 @@ impl Server { pub fn user_keys(&self) -> Vec { let mut output = Vec::new(); - for (user_key, _) in self.users.iter() { - output.push(user_key); + for (user_key, user) in self.users.iter() { + if self.user_connections.contains_key(&user.address) { + output.push(user_key); + } } output From ab3343102fedbf5393805d4defc4b0fb192c6434 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 12 Jan 2024 15:52:49 -0600 Subject: [PATCH 03/99] - new `client.connection_status()` method is more reliable than separate `is_connected()`,`is_connecting()`, & `is_disconnected()` methods - fixed hecs demos and crates --- adapters/bevy/client/src/client.rs | 10 ++-- adapters/hecs/shared/src/lib.rs | 2 +- adapters/hecs/shared/src/world_proxy.rs | 38 +++++++++++++-- adapters/hecs/shared/src/world_wrapper.rs | 38 +++++++++++++-- client/src/client.rs | 46 +++++++++++++++++-- client/src/lib.rs | 2 +- demos/basic/client/app/src/app.rs | 10 +--- demos/hecs/client/src/systems/events.rs | 2 +- demos/macroquad/client/src/app.rs | 4 +- .../shared/src/messages/entity_assignment.rs | 2 +- .../shared/src/messages/key_command.rs | 2 +- shared/src/lib.rs | 2 +- socket/client/Cargo.toml | 2 +- 13 files changed, 123 insertions(+), 37 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index da5da19e5..6b3a88d9d 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -9,7 +9,7 @@ use naia_bevy_shared::{ Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, GlobalEntity, Message, Tick, }; -use naia_client::{shared::SocketConfig, transport::Socket, Client as NaiaClient, NaiaClientError}; +use naia_client::{shared::SocketConfig, transport::Socket, Client as NaiaClient, NaiaClientError, ConnectionStatus}; use crate::ReplicationConfig; @@ -36,12 +36,8 @@ impl<'w> Client<'w> { self.client.disconnect(); } - pub fn is_connected(&self) -> bool { - self.client.is_connected() - } - - pub fn is_connecting(&self) -> bool { - self.client.is_connecting() + pub fn connection_status(&self) -> ConnectionStatus { + self.client.connection_status() } pub fn server_address(&self) -> Result { diff --git a/adapters/hecs/shared/src/lib.rs b/adapters/hecs/shared/src/lib.rs index b46b7a747..44c140769 100644 --- a/adapters/hecs/shared/src/lib.rs +++ b/adapters/hecs/shared/src/lib.rs @@ -6,7 +6,7 @@ pub use naia_shared::{ MessageHecs as Message, MessageKind, MessageKinds, Named, OwnedBitReader, OwnedLocalEntity, Property, PropertyMutate, PropertyMutator, Random, ReliableSettings, RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBuilder, ReplicateHecs as Replicate, SerdeErr, - SerdeHecs as Serde, TickBufferSettings, UnsignedInteger, + SerdeHecs as Serde, TickBufferSettings, UnsignedInteger, EntityAuthAccessor }; mod component_access; diff --git a/adapters/hecs/shared/src/world_proxy.rs b/adapters/hecs/shared/src/world_proxy.rs index 6c6d6e3d7..c4f9f7ed6 100644 --- a/adapters/hecs/shared/src/world_proxy.rs +++ b/adapters/hecs/shared/src/world_proxy.rs @@ -1,10 +1,6 @@ use hecs::{Entity, World}; -use naia_shared::{ - ComponentFieldUpdate, ComponentKind, ComponentUpdate, LocalEntityAndGlobalEntityConverter, - ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, - SerdeErr, WorldMutType, WorldRefType, -}; +use naia_shared::{ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType}; use super::{ component_ref::{ComponentMut, ComponentRef}, @@ -273,6 +269,38 @@ impl<'w, 'd> WorldMutType for WorldMut<'w, 'd> { } None } + + fn entity_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + todo!() + } + + fn component_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } + + fn entity_unpublish(&mut self, _entity: &Entity) { + todo!() + } + + fn component_unpublish(&mut self, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } + + fn entity_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + todo!() + } + + fn component_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } + + fn entity_disable_delegation(&mut self, _entity: &Entity) { + todo!() + } + + fn component_disable_delegation(&mut self, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } } // private static methods diff --git a/adapters/hecs/shared/src/world_wrapper.rs b/adapters/hecs/shared/src/world_wrapper.rs index 3dd3b3208..cdbe1ed03 100644 --- a/adapters/hecs/shared/src/world_wrapper.rs +++ b/adapters/hecs/shared/src/world_wrapper.rs @@ -5,11 +5,7 @@ use std::{ use hecs::{Entity, World}; -use naia_shared::{ - ComponentFieldUpdate, ComponentKind, ComponentUpdate, LocalEntityAndGlobalEntityConverter, - ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, - SerdeErr, WorldMutType, WorldRefType, -}; +use naia_shared::{ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType}; use crate::{ component_ref::{ComponentMut, ComponentRef}, @@ -258,6 +254,38 @@ impl WorldMutType for &mut WorldWrapper { } None } + + fn entity_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + todo!() + } + + fn component_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } + + fn entity_unpublish(&mut self, _entity: &Entity) { + todo!() + } + + fn component_unpublish(&mut self, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } + + fn entity_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + todo!() + } + + fn component_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } + + fn entity_disable_delegation(&mut self, _entity: &Entity) { + todo!() + } + + fn component_disable_delegation(&mut self, _entity: &Entity, _component_kind: &ComponentKind) { + todo!() + } } // private static methods diff --git a/client/src/client.rs b/client/src/client.rs index 35f36495b..2c0d44d00 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -106,18 +106,32 @@ impl Client { self.io.load(packet_sender, packet_receiver); } + /// Returns client's current connection status + pub fn connection_status(&self) -> ConnectionStatus { + if self.is_disconnected() { + return ConnectionStatus::Disconnected; + } + if self.is_connecting() { + return ConnectionStatus::Connecting; + } + if self.is_connected() { + return ConnectionStatus::Connected; + } + return ConnectionStatus::Disconnecting; + } + /// Returns whether or not the client is disconnected - pub fn is_disconnected(&self) -> bool { + fn is_disconnected(&self) -> bool { !self.io.is_loaded() } /// Returns whether or not a connection is being established with the Server - pub fn is_connecting(&self) -> bool { + fn is_connecting(&self) -> bool { self.io.is_loaded() } /// Returns whether or not a connection has been established with the Server - pub fn is_connected(&self) -> bool { + fn is_connected(&self) -> bool { self.server_connection.is_some() } @@ -1274,3 +1288,29 @@ impl EntityAndGlobalEntityConverter for Cl self.global_world_manager.entity_to_global_entity(entity) } } + +#[derive(Copy, Clone, PartialEq, Eq)] +pub enum ConnectionStatus { + Disconnected, + Connecting, + Connected, + Disconnecting, +} + +impl ConnectionStatus { + pub fn is_disconnected(&self) -> bool { + self == &ConnectionStatus::Disconnected + } + + pub fn is_connecting(&self) -> bool { + self == &ConnectionStatus::Connecting + } + + pub fn is_connected(&self) -> bool { + self == &ConnectionStatus::Connected + } + + pub fn is_disconnecting(&self) -> bool { + self == &ConnectionStatus::Disconnecting + } +} \ No newline at end of file diff --git a/client/src/lib.rs b/client/src/lib.rs index 34adf2bb4..bd79466d9 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -31,7 +31,7 @@ mod error; mod events; mod world; -pub use client::Client; +pub use client::{Client, ConnectionStatus}; pub use client_config::ClientConfig; pub use command_history::CommandHistory; pub use error::NaiaClientError; diff --git a/demos/basic/client/app/src/app.rs b/demos/basic/client/app/src/app.rs index 12d8434bf..a80ccd660 100644 --- a/demos/basic/client/app/src/app.rs +++ b/demos/basic/client/app/src/app.rs @@ -6,13 +6,7 @@ cfg_if! { } } -use naia_client::{ - shared::{default_channels::UnorderedReliableChannel, SocketConfig}, - transport::webrtc, - Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, DespawnEntityEvent, - DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, RemoveComponentEvent, SpawnEntityEvent, - UpdateComponentEvent, -}; +use naia_client::{shared::{default_channels::UnorderedReliableChannel, SocketConfig}, transport::webrtc, Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, RemoveComponentEvent, SpawnEntityEvent, UpdateComponentEvent, ConnectionStatus}; use naia_demo_world::{Entity, World}; @@ -51,7 +45,7 @@ impl App { } pub fn update(&mut self) { - if self.client.is_disconnected() { + if self.client.connection_status() != ConnectionStatus::Connected { return; } diff --git a/demos/hecs/client/src/systems/events.rs b/demos/hecs/client/src/systems/events.rs index 283e3af37..e0b767f52 100644 --- a/demos/hecs/client/src/systems/events.rs +++ b/demos/hecs/client/src/systems/events.rs @@ -9,7 +9,7 @@ use naia_hecs_demo_shared::{Marker, Name, Position}; use crate::app::App; pub fn process_events(app: &mut App) { - if app.client.is_disconnected() { + if !app.client.connection_status().is_connected() { return; } diff --git a/demos/macroquad/client/src/app.rs b/demos/macroquad/client/src/app.rs index 1411e0905..c61d06a01 100644 --- a/demos/macroquad/client/src/app.rs +++ b/demos/macroquad/client/src/app.rs @@ -129,7 +129,7 @@ impl App { } fn receive_events(&mut self) { - if self.client.is_disconnected() { + if !self.client.connection_status().is_connected() { return; } @@ -300,7 +300,7 @@ impl App { fn draw(&mut self) { clear_background(BLACK); - if !self.client.is_connected() { + if !self.client.connection_status().is_connected() { return; } diff --git a/demos/macroquad/shared/src/messages/entity_assignment.rs b/demos/macroquad/shared/src/messages/entity_assignment.rs index b9705edc0..17d7b54ed 100644 --- a/demos/macroquad/shared/src/messages/entity_assignment.rs +++ b/demos/macroquad/shared/src/messages/entity_assignment.rs @@ -10,7 +10,7 @@ impl EntityAssignment { pub fn new(assign: bool) -> Self { Self { assign, - entity: EntityProperty::new_local(), + entity: EntityProperty::new(), } } } diff --git a/demos/macroquad/shared/src/messages/key_command.rs b/demos/macroquad/shared/src/messages/key_command.rs index 9a9f2d0ed..5fa83eb4c 100644 --- a/demos/macroquad/shared/src/messages/key_command.rs +++ b/demos/macroquad/shared/src/messages/key_command.rs @@ -16,7 +16,7 @@ impl KeyCommand { s, a, d, - entity: EntityProperty::new_local(), + entity: EntityProperty::new(), } } } diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 627577889..3aeca57dd 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -115,7 +115,7 @@ pub use world::{ }, error::EntityDoesNotExistError, global_entity::GlobalEntity, - local_entity::{HostEntity, RemoteEntity}, + local_entity::{HostEntity, RemoteEntity, OwnedLocalEntity}, }, host::{ global_diff_handler::GlobalDiffHandler, diff --git a/socket/client/Cargo.toml b/socket/client/Cargo.toml index 50424afe8..c70c8559b 100644 --- a/socket/client/Cargo.toml +++ b/socket/client/Cargo.toml @@ -34,7 +34,7 @@ tinyjson = { version = "2.3", optional = true } miniquad = { version = "0.3", features = ["log-impl"], optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -webrtc-unreliable-client = { version = "0.2" } +webrtc-unreliable-client = { path = "../../../webrtc-unreliable-client/client" } tokio = { version = "1.15", features = ["full"] } once_cell = { version = "1.4.1" } From 68253676934e1bd34231d2a31d9129955259b20a Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 13 Jan 2024 15:09:14 -0600 Subject: [PATCH 04/99] - expose `default_channels` to bevy adapter crates --- adapters/bevy/client/src/lib.rs | 2 +- adapters/bevy/server/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 96b9eca19..15f9878f3 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -2,7 +2,7 @@ pub use naia_bevy_shared::{ sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, }; pub use naia_client::{ - shared::Instant, transport, ClientConfig, CommandHistory, ReplicationConfig, + shared::{Instant, default_channels}, transport, ClientConfig, CommandHistory, ReplicationConfig, }; pub mod events; diff --git a/adapters/bevy/server/src/lib.rs b/adapters/bevy/server/src/lib.rs index 019c2b510..0e2204f82 100644 --- a/adapters/bevy/server/src/lib.rs +++ b/adapters/bevy/server/src/lib.rs @@ -2,7 +2,7 @@ pub use naia_bevy_shared::{EntityAuthStatus, Random, ReceiveEvents, Replicate, T pub use naia_server::{ shared::{ BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, SerdeErr, - SignedInteger, SignedVariableInteger, UnsignedInteger, UnsignedVariableInteger, + SignedInteger, SignedVariableInteger, UnsignedInteger, UnsignedVariableInteger, default_channels, }, transport, ReplicationConfig, RoomKey, SerdeBevy as Serde, ServerConfig, UserKey, }; From 1fb014607b247d0d4fb75367bc4089f46cb2d860 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 13 Jan 2024 15:17:36 -0600 Subject: [PATCH 05/99] - revert accidental local-development-only Cargo.toml change --- socket/client/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/socket/client/Cargo.toml b/socket/client/Cargo.toml index c70c8559b..50424afe8 100644 --- a/socket/client/Cargo.toml +++ b/socket/client/Cargo.toml @@ -34,7 +34,7 @@ tinyjson = { version = "2.3", optional = true } miniquad = { version = "0.3", features = ["log-impl"], optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -webrtc-unreliable-client = { path = "../../../webrtc-unreliable-client/client" } +webrtc-unreliable-client = { version = "0.2" } tokio = { version = "1.15", features = ["full"] } once_cell = { version = "1.4.1" } From ae5cbd5a9361a316d8eb1f290a0cee6ad340a453 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 13 Jan 2024 15:43:19 -0600 Subject: [PATCH 06/99] - fix Client's connection status reasoning --- client/src/client.rs | 50 ++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 18 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 2c0d44d00..6ebcd1e9a 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -108,21 +108,21 @@ impl Client { /// Returns client's current connection status pub fn connection_status(&self) -> ConnectionStatus { - if self.is_disconnected() { - return ConnectionStatus::Disconnected; - } - if self.is_connecting() { - return ConnectionStatus::Connecting; - } if self.is_connected() { - return ConnectionStatus::Connected; + if self.is_disconnecting() { + return ConnectionStatus::Disconnecting; + } else { + return ConnectionStatus::Connected; + } + } else { + if self.is_disconnected() { + return ConnectionStatus::Disconnected; + } + if self.is_connecting() { + return ConnectionStatus::Connecting; + } + panic!("Client is in an unknown connection state!"); } - return ConnectionStatus::Disconnecting; - } - - /// Returns whether or not the client is disconnected - fn is_disconnected(&self) -> bool { - !self.io.is_loaded() } /// Returns whether or not a connection is being established with the Server @@ -135,6 +135,20 @@ impl Client { self.server_connection.is_some() } + /// Returns whether or not the client is disconnecting + fn is_disconnecting(&self) -> bool { + if let Some(connection) = &self.server_connection { + connection.base.should_drop() || self.manual_disconnect + } else { + false + } + } + + /// Returns whether or not the client is disconnected + fn is_disconnected(&self) -> bool { + !self.io.is_loaded() + } + /// Disconnect from Server pub fn disconnect(&mut self) { if !self.is_connected() { @@ -172,12 +186,12 @@ impl Client { let mut response_events = None; // all other operations - if let Some(connection) = &mut self.server_connection { - if connection.base.should_drop() || self.manual_disconnect { - self.disconnect_with_events(&mut world); - return std::mem::take(&mut self.incoming_events); - } + if self.is_disconnecting() { + self.disconnect_with_events(&mut world); + return std::mem::take(&mut self.incoming_events); + } + if let Some(connection) = &mut self.server_connection { let (receiving_tick_happened, sending_tick_happened) = connection.time_manager.collect_ticks(); From 3687436f75f55498a99b91da9124219aaccf578d Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 13 Jan 2024 16:49:45 -0600 Subject: [PATCH 07/99] rename BitWrite.write_bits() -> count_bits() to better reflect it's usage --- client/src/connection/tick_buffer_sender.rs | 2 +- shared/serde/src/bit_counter.rs | 2 +- shared/serde/src/bit_writer.rs | 5 +++-- shared/serde/src/file_bit_writer.rs | 2 +- shared/src/messages/channels/senders/message_fragmenter.rs | 2 +- shared/src/messages/message_container.rs | 2 +- shared/src/messages/message_manager.rs | 2 +- shared/src/world/host/host_world_writer.rs | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/client/src/connection/tick_buffer_sender.rs b/client/src/connection/tick_buffer_sender.rs index f7c663cf4..ac244d8cd 100644 --- a/client/src/connection/tick_buffer_sender.rs +++ b/client/src/connection/tick_buffer_sender.rs @@ -84,7 +84,7 @@ impl TickBufferSender { // write ChannelContinue bit true.ser(&mut counter); // write ChannelIndex - counter.write_bits(::const_bit_length()); + counter.count_bits(::const_bit_length()); if counter.overflowed() { break; diff --git a/shared/serde/src/bit_counter.rs b/shared/serde/src/bit_counter.rs index 321b9f985..6660165bd 100644 --- a/shared/serde/src/bit_counter.rs +++ b/shared/serde/src/bit_counter.rs @@ -32,7 +32,7 @@ impl BitWrite for BitCounter { fn write_byte(&mut self, _: u8) { self.current_bits += 8; } - fn write_bits(&mut self, bits: u32) { + fn count_bits(&mut self, bits: u32) { self.current_bits += bits; } fn is_counter(&self) -> bool { diff --git a/shared/serde/src/bit_writer.rs b/shared/serde/src/bit_writer.rs index 1e5c719e6..aafd83209 100644 --- a/shared/serde/src/bit_writer.rs +++ b/shared/serde/src/bit_writer.rs @@ -7,8 +7,9 @@ use crate::{ pub trait BitWrite { fn write_bit(&mut self, bit: bool); fn write_byte(&mut self, byte: u8); - fn write_bits(&mut self, bits: u32); + fn is_counter(&self) -> bool; + fn count_bits(&mut self, bits: u32); } // BitWriter @@ -117,7 +118,7 @@ impl BitWrite for BitWriter { } } - fn write_bits(&mut self, _: u32) { + fn count_bits(&mut self, _: u32) { panic!("This method should not be called for BitWriter!"); } diff --git a/shared/serde/src/file_bit_writer.rs b/shared/serde/src/file_bit_writer.rs index d94a295ab..7e860c121 100644 --- a/shared/serde/src/file_bit_writer.rs +++ b/shared/serde/src/file_bit_writer.rs @@ -56,7 +56,7 @@ impl BitWrite for FileBitWriter { } } - fn write_bits(&mut self, _: u32) { + fn count_bits(&mut self, _: u32) { panic!("This method should not be called for FileBitWriter!"); } diff --git a/shared/src/messages/channels/senders/message_fragmenter.rs b/shared/src/messages/channels/senders/message_fragmenter.rs index 6b5fc09f2..2838b8dc6 100644 --- a/shared/src/messages/channels/senders/message_fragmenter.rs +++ b/shared/src/messages/channels/senders/message_fragmenter.rs @@ -94,7 +94,7 @@ impl BitWrite for FragmentWriter { } } - fn write_bits(&mut self, _bits: u32) { + fn count_bits(&mut self, _bits: u32) { panic!("This method should only be used by BitCounter"); } diff --git a/shared/src/messages/message_container.rs b/shared/src/messages/message_container.rs index 131cbf482..b673682c8 100644 --- a/shared/src/messages/message_container.rs +++ b/shared/src/messages/message_container.rs @@ -49,7 +49,7 @@ impl MessageContainer { converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, ) { if writer.is_counter() { - writer.write_bits(self.bit_length()); + writer.count_bits(self.bit_length()); } else { self.inner.write(message_kinds, writer, converter); } diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index 0fac79bb8..72ca99ffe 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -233,7 +233,7 @@ impl MessageManager { // write ChannelContinue bit counter.write_bit(false); // write ChannelIndex - counter.write_bits(::const_bit_length()); + counter.count_bits(::const_bit_length()); if counter.overflowed() { break; } diff --git a/shared/src/world/host/host_world_writer.rs b/shared/src/world/host/host_world_writer.rs index 9e4346eb4..4059e2b0e 100644 --- a/shared/src/world/host/host_world_writer.rs +++ b/shared/src/world/host/host_world_writer.rs @@ -469,7 +469,7 @@ impl HostWorldWriter { // write ComponentContinue bit true.ser(&mut counter); // write component kind - counter.write_bits(::const_bit_length()); + counter.count_bits(::const_bit_length()); // write data world .component_of_kind(entity, component_kind) From 4dc9f35e44017c4c9cbf70239c53c27c7ff68581 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 13 Jan 2024 19:08:18 -0600 Subject: [PATCH 08/99] - "bevy_support" feature on server/client now just passes the feature down into the naia_shared crate, figured out how to remove that dependency in the server/client code - `naia_bevy_client` API is changing somewhat to allow for multiple clients in the same app --- adapters/bevy/client/src/client.rs | 71 +++++---- adapters/bevy/client/src/commands.rs | 52 +++---- adapters/bevy/client/src/events.rs | 209 +++++++++++++++++++++++---- adapters/bevy/client/src/plugin.rs | 48 +++--- adapters/bevy/client/src/systems.rs | 82 +++++------ adapters/bevy/server/src/commands.rs | 8 +- adapters/bevy/server/src/plugin.rs | 2 + adapters/bevy/server/src/server.rs | 71 ++++----- adapters/bevy/server/src/systems.rs | 27 ++-- client/Cargo.toml | 3 +- client/src/client.rs | 4 - server/Cargo.toml | 3 +- server/src/server.rs | 4 - 13 files changed, 377 insertions(+), 207 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 6b3a88d9d..860e699cd 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -1,8 +1,8 @@ -use std::net::SocketAddr; +use std::{net::SocketAddr, marker::PhantomData}; use bevy_ecs::{ entity::Entity, - system::{ResMut, SystemParam}, + system::{Resource, ResMut, SystemParam}, }; use naia_bevy_shared::{ @@ -13,118 +13,133 @@ use naia_client::{shared::SocketConfig, transport::Socket, Client as NaiaClient, use crate::ReplicationConfig; +#[derive(Resource)] +pub struct ClientWrapper { + pub client: NaiaClient, + phantom_t: PhantomData, +} + +impl ClientWrapper { + pub fn new(client: NaiaClient) -> Self { + Self { + client, + phantom_t: PhantomData, + } + } +} + // Client #[derive(SystemParam)] -pub struct Client<'w> { - client: ResMut<'w, NaiaClient>, +pub struct Client<'w, T: Send + Sync + 'static> { + client: ResMut<'w, ClientWrapper>, } -impl<'w> Client<'w> { +impl<'w, T: Send + Sync + 'static> Client<'w, T> { // Public Methods // //// Connections //// pub fn auth(&mut self, auth: M) { - self.client.auth(auth); + self.client.client.auth(auth); } pub fn connect>>(&mut self, socket: S) { - self.client.connect(socket); + self.client.client.connect(socket); } pub fn disconnect(&mut self) { - self.client.disconnect(); + self.client.client.disconnect(); } pub fn connection_status(&self) -> ConnectionStatus { - self.client.connection_status() + self.client.client.connection_status() } pub fn server_address(&self) -> Result { - self.client.server_address() + self.client.client.server_address() } pub fn rtt(&self) -> f32 { - self.client.rtt() + self.client.client.rtt() } pub fn jitter(&self) -> f32 { - self.client.jitter() + self.client.client.jitter() } // Config pub fn socket_config(&self) -> &SocketConfig { - self.client.socket_config() + self.client.client.socket_config() } //// Messages //// pub fn send_message(&mut self, message: &M) { - self.client.send_message::(message); + self.client.client.send_message::(message); } pub fn send_tick_buffer_message(&mut self, tick: &Tick, message: &M) { - self.client.send_tick_buffer_message::(tick, message); + self.client.client.send_tick_buffer_message::(tick, message); } //// Ticks //// pub fn client_tick(&self) -> Option { - self.client.client_tick() + self.client.client.client_tick() } pub fn server_tick(&self) -> Option { - self.client.server_tick() + self.client.client.server_tick() } // Interpolation pub fn client_interpolation(&self) -> Option { - self.client.client_interpolation() + self.client.client.client_interpolation() } pub fn server_interpolation(&self) -> Option { - self.client.server_interpolation() + self.client.client.server_interpolation() } // Entity Registration pub(crate) fn enable_replication(&mut self, entity: &Entity) { - self.client.enable_entity_replication(entity); + self.client.client.enable_entity_replication(entity); } pub(crate) fn disable_replication(&mut self, entity: &Entity) { - self.client.disable_entity_replication(entity); + self.client.client.disable_entity_replication(entity); } pub(crate) fn replication_config(&self, entity: &Entity) -> Option { - self.client.entity_replication_config(entity) + self.client.client.entity_replication_config(entity) } pub(crate) fn entity_request_authority(&mut self, entity: &Entity) { - self.client.entity_request_authority(entity); + self.client.client.entity_request_authority(entity); } pub(crate) fn entity_release_authority(&mut self, entity: &Entity) { - self.client.entity_release_authority(entity); + self.client.client.entity_release_authority(entity); } pub(crate) fn entity_authority_status(&self, entity: &Entity) -> Option { - self.client.entity_authority_status(entity) + self.client.client.entity_authority_status(entity) } } -impl<'w> EntityAndGlobalEntityConverter for Client<'w> { +impl<'w, T: Send + Sync + 'static> EntityAndGlobalEntityConverter for Client<'w, T> { fn global_entity_to_entity( &self, global_entity: &GlobalEntity, ) -> Result { - self.client.global_entity_to_entity(global_entity) + self.client.client.global_entity_to_entity(global_entity) } fn entity_to_global_entity( &self, entity: &Entity, ) -> Result { - self.client.entity_to_global_entity(entity) + self.client.client.entity_to_global_entity(entity) } } diff --git a/adapters/bevy/client/src/commands.rs b/adapters/bevy/client/src/commands.rs index 9cbb3fc1e..12fd963bb 100644 --- a/adapters/bevy/client/src/commands.rs +++ b/adapters/bevy/client/src/commands.rs @@ -1,3 +1,4 @@ +use std::marker::PhantomData; use bevy_ecs::{ entity::Entity, system::{Command as BevyCommand, EntityCommands}, @@ -5,24 +6,24 @@ use bevy_ecs::{ }; use naia_bevy_shared::{EntityAuthStatus, HostOwned, WorldMutType, WorldProxyMut}; -use naia_client::{Client as NaiaClient, ReplicationConfig}; +use naia_client::ReplicationConfig; -use crate::Client; +use crate::{Client, client::ClientWrapper}; // Bevy Commands Extension pub trait CommandsExt<'w, 's, 'a> { fn local_duplicate(&'a mut self) -> EntityCommands<'w, 's, 'a>; - fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; - fn disable_replication(&'a mut self, client: &mut Client) - -> &'a mut EntityCommands<'w, 's, 'a>; - fn configure_replication( + fn configure_replication( &'a mut self, config: ReplicationConfig, ) -> &'a mut EntityCommands<'w, 's, 'a>; - fn replication_config(&'a self, client: &Client) -> Option; - fn request_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; - fn release_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; - fn authority(&'a self, client: &Client) -> Option; + fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; + fn disable_replication(&'a mut self, client: &mut Client) + -> &'a mut EntityCommands<'w, 's, 'a>; + fn replication_config(&'a self, client: &Client) -> Option; + fn request_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; + fn release_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; + fn authority(&'a self, client: &Client) -> Option; } impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { @@ -35,47 +36,47 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { commands.entity(new_entity) } - fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { + fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { client.enable_replication(&self.id()); self.insert(HostOwned); return self; } - fn disable_replication( + fn disable_replication( &'a mut self, - client: &mut Client, + client: &mut Client, ) -> &'a mut EntityCommands<'w, 's, 'a> { client.disable_replication(&self.id()); self.remove::(); return self; } - fn configure_replication( + fn configure_replication( &'a mut self, config: ReplicationConfig, ) -> &'a mut EntityCommands<'w, 's, 'a> { let entity = self.id(); let commands = self.commands(); - let command = ConfigureReplicationCommand::new(entity, config); + let command = ConfigureReplicationCommand::::new(entity, config); commands.add(command); return self; } - fn replication_config(&'a self, client: &Client) -> Option { + fn replication_config(&'a self, client: &Client) -> Option { client.replication_config(&self.id()) } - fn request_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { + fn request_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { client.entity_request_authority(&self.id()); return self; } - fn release_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { + fn release_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { client.entity_release_authority(&self.id()); return self; } - fn authority(&'a self, client: &Client) -> Option { + fn authority(&'a self, client: &Client) -> Option { client.entity_authority_status(&self.id()) } } @@ -106,21 +107,22 @@ impl BevyCommand for LocalDuplicateComponents { } //// ConfigureReplicationCommand Command //// -pub(crate) struct ConfigureReplicationCommand { +pub(crate) struct ConfigureReplicationCommand { entity: Entity, config: ReplicationConfig, + phantom_t: PhantomData, } -impl ConfigureReplicationCommand { +impl ConfigureReplicationCommand { pub fn new(entity: Entity, config: ReplicationConfig) -> Self { - Self { entity, config } + Self { entity, config, phantom_t: PhantomData } } } -impl BevyCommand for ConfigureReplicationCommand { +impl BevyCommand for ConfigureReplicationCommand { fn apply(self, world: &mut World) { - world.resource_scope(|world, mut client: Mut>| { - client.configure_entity_replication(&mut world.proxy_mut(), &self.entity, self.config); + world.resource_scope(|world, mut client: Mut>| { + client.client.configure_entity_replication(&mut world.proxy_mut(), &self.entity, self.config); }); } } diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 3263a1e28..9b3b1d57f 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -1,4 +1,4 @@ -use std::{any::Any, collections::HashMap}; +use std::{any::Any, collections::HashMap, marker::PhantomData}; use bevy_ecs::{entity::Entity, prelude::Event}; @@ -10,35 +10,79 @@ use naia_bevy_shared::{ // ConnectEvent #[derive(Event)] -pub struct ConnectEvent; +pub struct ConnectEvent { + phantom_t: PhantomData, +} + +impl ConnectEvent { + pub fn new() -> Self { + Self { + phantom_t: PhantomData, + } + } +} // DisconnectEvent #[derive(Event)] -pub struct DisconnectEvent; +pub struct DisconnectEvent { + phantom_t: PhantomData, +} + +impl DisconnectEvent { + pub fn new() -> Self { + Self { + phantom_t: PhantomData, + } + } +} // RejectEvent #[derive(Event)] -pub struct RejectEvent; +pub struct RejectEvent { + phantom_t: PhantomData, +} + +impl RejectEvent { + pub fn new() -> Self { + Self { + phantom_t: PhantomData, + } + } +} // ErrorEvent #[derive(Event)] -pub struct ErrorEvent(pub NaiaClientError); +pub struct ErrorEvent { + pub err: NaiaClientError, + phantom_t: PhantomData, +} + +impl ErrorEvent { + pub fn new(err: NaiaClientError) -> Self { + Self { + err, + phantom_t: PhantomData, + } + } +} // MessageEvents #[derive(Event)] -pub struct MessageEvents { +pub struct MessageEvents { inner: HashMap>>, + phantom_t: PhantomData, } -impl From<&mut Events> for MessageEvents { +impl From<&mut Events> for MessageEvents { fn from(events: &mut Events) -> Self { Self { inner: events.take_messages(), + phantom_t: PhantomData, } } } -impl MessageEvents { +impl MessageEvents { pub fn read(&self) -> Vec { let mut output = Vec::new(); @@ -63,49 +107,158 @@ impl MessageEvents { // ClientTickEvent #[derive(Event)] -pub struct ClientTickEvent(pub Tick); +pub struct ClientTickEvent { + pub tick: Tick, + phantom_t: PhantomData, +} + +impl ClientTickEvent { + pub fn new(tick: Tick) -> Self { + Self { + tick, + phantom_t: PhantomData, + } + } +} // ServerTickEvent #[derive(Event)] -pub struct ServerTickEvent(pub Tick); +pub struct ServerTickEvent { + pub tick: Tick, + phantom_t: PhantomData, +} + +impl ServerTickEvent { + pub fn new(tick: Tick) -> Self { + Self { + tick, + phantom_t: PhantomData, + } + } +} // SpawnEntityEvent #[derive(Event)] -pub struct SpawnEntityEvent(pub Entity); +pub struct SpawnEntityEvent { + pub entity: Entity, + phantom_t: PhantomData, +} + +impl SpawnEntityEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: PhantomData, + } + } +} // DespawnEntityEvent #[derive(Event)] -pub struct DespawnEntityEvent(pub Entity); +pub struct DespawnEntityEvent { + pub entity: Entity, + phantom_t: PhantomData, +} + +impl DespawnEntityEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: PhantomData, + } + } +} // PublishEntityEvent #[derive(Event)] -pub struct PublishEntityEvent(pub Entity); +pub struct PublishEntityEvent { + pub entity: Entity, + phantom_t: PhantomData, +} + +impl PublishEntityEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: PhantomData, + } + } +} // UnpublishEntityEvent #[derive(Event)] -pub struct UnpublishEntityEvent(pub Entity); +pub struct UnpublishEntityEvent { + pub entity: Entity, + phantom_t: PhantomData, +} + +impl UnpublishEntityEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: PhantomData, + } + } +} // EntityAuthGrantedEvent #[derive(Event)] -pub struct EntityAuthGrantedEvent(pub Entity); +pub struct EntityAuthGrantedEvent { + pub entity: Entity, + phantom_t: PhantomData, +} + +impl EntityAuthGrantedEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: PhantomData, + } + } +} // EntityAuthDeniedEvent #[derive(Event)] -pub struct EntityAuthDeniedEvent(pub Entity); +pub struct EntityAuthDeniedEvent { + pub entity: Entity, + phantom_t: PhantomData, +} + +impl EntityAuthDeniedEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: PhantomData, + } + } +} // EntityAuthResetEvent #[derive(Event)] -pub struct EntityAuthResetEvent(pub Entity); +pub struct EntityAuthResetEvent { + pub entity: Entity, + phantom_t: PhantomData, +} + +impl EntityAuthResetEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: PhantomData, + } + } +} // InsertComponentEvent #[derive(Event, Clone)] -pub struct InsertComponentEvents { +pub struct InsertComponentEvents { inner: HashMap>, + phantom_t: PhantomData, } -impl InsertComponentEvents { +impl InsertComponentEvents { pub fn new(inner: HashMap>) -> Self { - Self { inner } + Self { inner, phantom_t: PhantomData } } pub fn read(&self) -> Vec { let component_kind = ComponentKind::of::(); @@ -119,13 +272,14 @@ impl InsertComponentEvents { // UpdateComponentEvents #[derive(Event, Clone)] -pub struct UpdateComponentEvents { +pub struct UpdateComponentEvents { inner: HashMap>, + phantom_t: PhantomData, } -impl UpdateComponentEvents { +impl UpdateComponentEvents { pub fn new(inner: HashMap>) -> Self { - Self { inner } + Self { inner, phantom_t: PhantomData } } pub fn read(&self) -> Vec<(Tick, Entity)> { @@ -140,16 +294,17 @@ impl UpdateComponentEvents { // RemoveComponentEvents #[derive(Event)] -pub struct RemoveComponentEvents { +pub struct RemoveComponentEvents { inner: HashMap)>>, + phantom_t: PhantomData, } -impl RemoveComponentEvents { +impl RemoveComponentEvents { pub fn new(inner: HashMap)>>) -> Self { - Self { inner } + Self { inner, phantom_t: PhantomData } } - pub fn clone_new(&self) -> RemoveComponentEvents { + pub fn clone_new(&self) -> Self { let mut output = HashMap::new(); for (key, value) in self.inner.iter() { diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index c386a3e34..887fc3473 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -1,4 +1,4 @@ -use std::{ops::DerefMut, sync::Mutex}; +use std::{marker::PhantomData, ops::DerefMut, sync::Mutex}; use bevy_app::{App, Plugin as PluginType, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs}; @@ -14,6 +14,7 @@ use super::{ SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvents, }, systems::before_receive_events, + client::ClientWrapper, }; struct PluginConfig { @@ -30,20 +31,22 @@ impl PluginConfig { } } -pub struct Plugin { +pub struct Plugin { config: Mutex>, + phantom_t: PhantomData, } -impl Plugin { +impl Plugin { pub fn new(client_config: ClientConfig, protocol: Protocol) -> Self { let config = PluginConfig::new(client_config, protocol); Self { config: Mutex::new(Some(config)), + phantom_t: PhantomData, } } } -impl PluginType for Plugin { +impl PluginType for Plugin { fn build(&self, app: &mut App) { let mut config = self.config.lock().unwrap().deref_mut().take().unwrap(); @@ -52,6 +55,7 @@ impl PluginType for Plugin { app.insert_resource(world_data); let client = Client::::new(config.client_config, config.protocol.into()); + let client = ClientWrapper::::new(client); app // SHARED PLUGIN // @@ -59,24 +63,24 @@ impl PluginType for Plugin { // RESOURCES // .insert_resource(client) // EVENTS // - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() - .add_event::() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() + .add_event::>() // SYSTEMS // - .add_systems(Update, before_receive_events.in_set(BeforeReceiveEvents)); + .add_systems(Update, before_receive_events::.in_set(BeforeReceiveEvents)); } } diff --git a/adapters/bevy/client/src/systems.rs b/adapters/bevy/client/src/systems.rs index 6fd953dbd..09e4bae11 100644 --- a/adapters/bevy/client/src/systems.rs +++ b/adapters/bevy/client/src/systems.rs @@ -3,13 +3,11 @@ use std::ops::DerefMut; use log::warn; use bevy_ecs::{ - entity::Entity, event::Events, world::{Mut, World}, }; use naia_bevy_shared::{HostOwned, HostSyncEvent, WorldMutType, WorldProxyMut}; -use naia_client::Client; mod naia_events { pub use naia_client::{ @@ -28,10 +26,10 @@ mod bevy_events { }; } -use crate::ServerOwned; +use crate::{ServerOwned, client::ClientWrapper}; -pub fn before_receive_events(world: &mut World) { - world.resource_scope(|world, mut client: Mut>| { +pub fn before_receive_events(world: &mut World) { + world.resource_scope(|world, mut client: Mut>| { // Host Component Updates let mut host_component_event_reader = world @@ -45,85 +43,85 @@ pub fn before_receive_events(world: &mut World) { let Some(mut component_mut) = world_proxy.component_mut_of_kind(&entity, &component_kind) else { continue; }; - client.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); + client.client.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); } HostSyncEvent::Remove(entity, component_kind) => { - client.remove_component_worldless(&entity, &component_kind); + client.client.remove_component_worldless(&entity, &component_kind); } HostSyncEvent::Despawn(entity) => { - client.despawn_entity_worldless(&entity); + client.client.despawn_entity_worldless(&entity); } } } // Receive Events - let mut events = client.receive(world.proxy_mut()); + let mut events = client.client.receive(world.proxy_mut()); if !events.is_empty() { if events.has::() { // Connect Event let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for _ in events.read::() { - event_writer.send(bevy_events::ConnectEvent); + event_writer.send(bevy_events::ConnectEvent::::new()); } } // Disconnect Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for _ in events.read::() { - event_writer.send(bevy_events::DisconnectEvent); + event_writer.send(bevy_events::DisconnectEvent::::new()); } } // Reject Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for _ in events.read::() { - event_writer.send(bevy_events::RejectEvent); + event_writer.send(bevy_events::RejectEvent::::new()); } } // Error Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for error in events.read::() { - event_writer.send(bevy_events::ErrorEvent(error)); + event_writer.send(bevy_events::ErrorEvent::::new(error)); } } // Client Tick Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for tick in events.read::() { - event_writer.send(bevy_events::ClientTickEvent(tick)); + event_writer.send(bevy_events::ClientTickEvent::::new(tick)); } } // Server Tick Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for tick in events.read::() { - event_writer.send(bevy_events::ServerTickEvent(tick)); + event_writer.send(bevy_events::ServerTickEvent::::new(tick)); } } // Message Event if events.has_messages() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); event_writer.send(bevy_events::MessageEvents::from(&mut events)); } @@ -131,13 +129,13 @@ pub fn before_receive_events(world: &mut World) { // Spawn Entity Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); let mut spawned_entities = Vec::new(); for entity in events.read::() { spawned_entities.push(entity); - event_writer.send(bevy_events::SpawnEntityEvent(entity)); + event_writer.send(bevy_events::SpawnEntityEvent::::new(entity)); } for entity in spawned_entities { world.entity_mut(entity).insert(ServerOwned); @@ -147,42 +145,42 @@ pub fn before_receive_events(world: &mut World) { // Despawn Entity Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for entity in events.read::() { - event_writer.send(bevy_events::DespawnEntityEvent(entity)); + event_writer.send(bevy_events::DespawnEntityEvent::::new(entity)); } } // Publish Entity Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for entity in events.read::() { - event_writer.send(bevy_events::PublishEntityEvent(entity)); + event_writer.send(bevy_events::PublishEntityEvent::::new(entity)); } } // Unpublish Entity Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for entity in events.read::() { - event_writer.send(bevy_events::UnpublishEntityEvent(entity)); + event_writer.send(bevy_events::UnpublishEntityEvent::::new(entity)); } } // Entity Auth Granted Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); let mut auth_granted_entities = Vec::new(); for entity in events.read::() { auth_granted_entities.push(entity); - event_writer.send(bevy_events::EntityAuthGrantedEvent(entity)); + event_writer.send(bevy_events::EntityAuthGrantedEvent::::new(entity)); } for entity in auth_granted_entities { if world.get_entity(entity).is_some() { @@ -196,22 +194,22 @@ pub fn before_receive_events(world: &mut World) { // Entity Auth Denied Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); for entity in events.read::() { - event_writer.send(bevy_events::EntityAuthDeniedEvent(entity)); + event_writer.send(bevy_events::EntityAuthDeniedEvent::::new(entity)); } } // Entity Auth Reset Event if events.has::() { let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); let mut auth_reset_entities = Vec::new(); for entity in events.read::() { auth_reset_entities.push(entity); - event_writer.send(bevy_events::EntityAuthResetEvent(entity)); + event_writer.send(bevy_events::EntityAuthResetEvent::::new(entity)); } for entity in auth_reset_entities { if world.get_entity(entity).is_some() { @@ -226,29 +224,29 @@ pub fn before_receive_events(world: &mut World) { if events.has_inserts() { let inserts = events.take_inserts().unwrap(); let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); - event_writer.send(bevy_events::InsertComponentEvents::new(inserts)); + event_writer.send(bevy_events::InsertComponentEvents::::new(inserts)); } // Update Component Event if events.has_updates() { let updates = events.take_updates().unwrap(); let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); event_writer - .send(bevy_events::UpdateComponentEvents::new(updates)); + .send(bevy_events::UpdateComponentEvents::::new(updates)); } // Remove Component Event if events.has_removes() { let removes = events.take_removes().unwrap(); let mut event_writer = world - .get_resource_mut::>() + .get_resource_mut::>>() .unwrap(); - event_writer.send(bevy_events::RemoveComponentEvents::new(removes)); + event_writer.send(bevy_events::RemoveComponentEvents::::new(removes)); } } }); diff --git a/adapters/bevy/server/src/commands.rs b/adapters/bevy/server/src/commands.rs index 114e443ab..2e3b730fd 100644 --- a/adapters/bevy/server/src/commands.rs +++ b/adapters/bevy/server/src/commands.rs @@ -5,9 +5,9 @@ use bevy_ecs::{ }; use naia_bevy_shared::{EntityAuthStatus, HostOwned, WorldProxyMut}; -use naia_server::{ReplicationConfig, Server as NaiaServer, UserKey}; +use naia_server::{ReplicationConfig, UserKey}; -use crate::Server; +use crate::{Server, server::ServerWrapper}; // Bevy Commands Extension pub trait CommandsExt<'w, 's, 'a> { @@ -103,8 +103,8 @@ impl ConfigureReplicationCommand { impl BevyCommand for ConfigureReplicationCommand { fn apply(self, world: &mut World) { - world.resource_scope(|world, mut server: Mut>| { - server.configure_entity_replication(&mut world.proxy_mut(), &self.entity, self.config); + world.resource_scope(|world, mut server: Mut| { + server.0.configure_entity_replication(&mut world.proxy_mut(), &self.entity, self.config); }); } } diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index 86c8b7bff..ddaa11522 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -13,6 +13,7 @@ use super::{ SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, }, systems::before_receive_events, + server::ServerWrapper, }; struct PluginConfig { @@ -51,6 +52,7 @@ impl PluginType for Plugin { app.insert_resource(world_data); let server = Server::::new(config.server_config, config.protocol.into()); + let server = ServerWrapper(server); app // SHARED PLUGIN // diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index 7e7f96457..fff8453bb 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -1,9 +1,11 @@ + use std::time::Duration; use bevy_ecs::{ entity::Entity, system::{ResMut, SystemParam}, }; +use bevy_ecs::prelude::Resource; use naia_server::{ shared::SocketConfig, transport::Socket, ReplicationConfig, RoomKey, RoomMut, RoomRef, @@ -15,11 +17,14 @@ use naia_bevy_shared::{ GlobalEntity, Message, Tick, }; +#[derive(Resource)] +pub struct ServerWrapper(pub NaiaServer); + // Server #[derive(SystemParam)] pub struct Server<'w> { - server: ResMut<'w, NaiaServer>, + server: ResMut<'w, ServerWrapper>, } impl<'w> Server<'w> { @@ -28,136 +33,136 @@ impl<'w> Server<'w> { //// Connections //// pub fn listen>>(&mut self, socket: S) { - self.server.listen(socket); + self.server.0.listen(socket); } pub fn is_listening(&self) -> bool { - self.server.is_listening() + self.server.0.is_listening() } pub fn accept_connection(&mut self, user_key: &UserKey) { - self.server.accept_connection(user_key); + self.server.0.accept_connection(user_key); } pub fn reject_connection(&mut self, user_key: &UserKey) { - self.server.reject_connection(user_key); + self.server.0.reject_connection(user_key); } // Config pub fn socket_config(&self) -> &SocketConfig { - self.server.socket_config() + self.server.0.socket_config() } //// Messages //// pub fn send_message(&mut self, user_key: &UserKey, message: &M) { - self.server.send_message::(user_key, message) + self.server.0.send_message::(user_key, message) } /// Sends a message to all connected users using a given channel pub fn broadcast_message(&mut self, message: &M) { - self.server.broadcast_message::(message); + self.server.0.broadcast_message::(message); } pub fn receive_tick_buffer_messages(&mut self, tick: &Tick) -> TickBufferMessages { - self.server.receive_tick_buffer_messages(tick) + self.server.0.receive_tick_buffer_messages(tick) } //// Updates //// pub fn scope_checks(&self) -> Vec<(RoomKey, UserKey, Entity)> { - self.server.scope_checks() + self.server.0.scope_checks() } //// Users //// pub fn user_exists(&self, user_key: &UserKey) -> bool { - self.server.user_exists(user_key) + self.server.0.user_exists(user_key) } pub fn user(&self, user_key: &UserKey) -> UserRef { - self.server.user(user_key) + self.server.0.user(user_key) } pub fn user_mut(&mut self, user_key: &UserKey) -> UserMut { - self.server.user_mut(user_key) + self.server.0.user_mut(user_key) } pub fn user_keys(&self) -> Vec { - self.server.user_keys() + self.server.0.user_keys() } pub fn users_count(&self) -> usize { - self.server.users_count() + self.server.0.users_count() } pub fn user_scope(&mut self, user_key: &UserKey) -> UserScopeMut { - self.server.user_scope(user_key) + self.server.0.user_scope(user_key) } //// Rooms //// pub fn make_room(&mut self) -> RoomMut { - self.server.make_room() + self.server.0.make_room() } pub fn room_exists(&self, room_key: &RoomKey) -> bool { - self.server.room_exists(room_key) + self.server.0.room_exists(room_key) } pub fn room(&self, room_key: &RoomKey) -> RoomRef { - self.server.room(room_key) + self.server.0.room(room_key) } pub fn room_mut(&mut self, room_key: &RoomKey) -> RoomMut { - self.server.room_mut(room_key) + self.server.0.room_mut(room_key) } pub fn room_keys(&self) -> Vec { - self.server.room_keys() + self.server.0.room_keys() } pub fn rooms_count(&self) -> usize { - self.server.rooms_count() + self.server.0.rooms_count() } //// Ticks //// pub fn current_tick(&self) -> Tick { - self.server.current_tick() + self.server.0.current_tick() } pub fn average_tick_duration(&self) -> Duration { - self.server.average_tick_duration() + self.server.0.average_tick_duration() } // Entity Replication pub(crate) fn enable_replication(&mut self, entity: &Entity) { - self.server.enable_entity_replication(entity); + self.server.0.enable_entity_replication(entity); } pub(crate) fn disable_replication(&mut self, entity: &Entity) { - self.server.disable_entity_replication(entity); + self.server.0.disable_entity_replication(entity); } pub(crate) fn pause_replication(&mut self, entity: &Entity) { - self.server.pause_entity_replication(entity); + self.server.0.pause_entity_replication(entity); } pub(crate) fn resume_replication(&mut self, entity: &Entity) { - self.server.resume_entity_replication(entity); + self.server.0.resume_entity_replication(entity); } pub(crate) fn replication_config(&self, entity: &Entity) -> Option { - self.server.entity_replication_config(entity) + self.server.0.entity_replication_config(entity) } pub(crate) fn entity_take_authority(&mut self, entity: &Entity) { - self.server.entity_take_authority(entity); + self.server.0.entity_take_authority(entity); } pub(crate) fn entity_authority_status(&self, entity: &Entity) -> Option { - self.server.entity_authority_status(entity) + self.server.0.entity_authority_status(entity) } } @@ -166,13 +171,13 @@ impl<'w> EntityAndGlobalEntityConverter for Server<'w> { &self, global_entity: &GlobalEntity, ) -> Result { - self.server.global_entity_to_entity(global_entity) + self.server.0.global_entity_to_entity(global_entity) } fn entity_to_global_entity( &self, entity: &Entity, ) -> Result { - self.server.entity_to_global_entity(entity) + self.server.0.entity_to_global_entity(entity) } } diff --git a/adapters/bevy/server/src/systems.rs b/adapters/bevy/server/src/systems.rs index 85dc96e0c..a77442215 100644 --- a/adapters/bevy/server/src/systems.rs +++ b/adapters/bevy/server/src/systems.rs @@ -1,7 +1,6 @@ use std::ops::DerefMut; use bevy_ecs::{ - entity::Entity, event::Events, world::{Mut, World}, }; @@ -9,9 +8,9 @@ use bevy_ecs::{ use log::warn; use naia_bevy_shared::{HostOwned, HostSyncEvent, WorldMutType, WorldProxy, WorldProxyMut}; -use naia_server::{EntityOwner, Server}; +use naia_server::EntityOwner; -use crate::{ClientOwned, EntityAuthStatus}; +use crate::{ClientOwned, EntityAuthStatus, server::ServerWrapper}; mod naia_events { pub use naia_server::{ @@ -31,8 +30,8 @@ mod bevy_events { } pub fn before_receive_events(world: &mut World) { - world.resource_scope(|world, mut server: Mut>| { - if !server.is_listening() { + world.resource_scope(|world, mut server: Mut| { + if !server.0.is_listening() { return; } @@ -44,7 +43,7 @@ pub fn before_receive_events(world: &mut World) { for event in host_component_events { match event { HostSyncEvent::Insert(entity, component_kind) => { - if server.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { + if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; } @@ -53,28 +52,28 @@ pub fn before_receive_events(world: &mut World) { warn!("could not find Component in World which has just been inserted!"); continue; }; - server.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); + server.0.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); } HostSyncEvent::Remove(entity, component_kind) => { - if server.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { + if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; } - server.remove_component_worldless(&entity, &component_kind); + server.0.remove_component_worldless(&entity, &component_kind); } HostSyncEvent::Despawn(entity) => { - if server.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { + if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; } - server.despawn_entity_worldless(&entity); + server.0.despawn_entity_worldless(&entity); } } } // Receive Events let mut did_tick = false; - let mut events = server.receive(world.proxy_mut()); + let mut events = server.0.receive(world.proxy_mut()); if !events.is_empty() { // Connect Event @@ -145,7 +144,7 @@ pub fn before_receive_events(world: &mut World) { event_writer.send(bevy_events::SpawnEntityEvent(user_key, entity)); } for entity in spawned_entities { - let EntityOwner::Client(user_key) = server.entity_owner(&entity) else { + let EntityOwner::Client(user_key) = server.0.entity_owner(&entity) else { panic!("spawned entity that doesn't belong to a client ... shouldn't be possible."); }; world.entity_mut(entity).insert(ClientOwned(user_key)); @@ -235,7 +234,7 @@ pub fn before_receive_events(world: &mut World) { } if did_tick { - server.send_all_updates(world.proxy()); + server.0.send_all_updates(world.proxy()); } } }); diff --git a/client/Cargo.toml b/client/Cargo.toml index ca92abd9e..a71247c90 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -19,7 +19,7 @@ maintenance = { status = "actively-developed" } [features] wbindgen = [ "naia-shared/wbindgen", "naia-client-socket?/wbindgen" ] mquad = [ "naia-shared/mquad", "naia-client-socket?/mquad" ] -bevy_support = ["naia-shared/bevy_support", "bevy_ecs"] +bevy_support = ["naia-shared/bevy_support"] zstd_support = ["naia-shared/zstd_support"] transport_webrtc = [ "naia-client-socket" ] transport_udp = [ "local_ipaddress" ] @@ -27,7 +27,6 @@ transport_udp = [ "local_ipaddress" ] [dependencies] naia-shared = { version = "0.22", path = "../shared" } naia-client-socket = { version = "0.22", path = "../socket/client", optional = true } -bevy_ecs = { version = "0.12.1", default_features = false, optional = true } local_ipaddress = { version = "0.1", optional = true } cfg-if = { version = "1.0" } log = { version = "0.4" } \ No newline at end of file diff --git a/client/src/client.rs b/client/src/client.rs index 6ebcd1e9a..e41d009d3 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -2,9 +2,6 @@ use std::{collections::VecDeque, hash::Hash, net::SocketAddr}; use log::{info, warn}; -#[cfg(feature = "bevy_support")] -use bevy_ecs::prelude::Resource; - use naia_shared::{ BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, @@ -32,7 +29,6 @@ use crate::{ /// Client can send/receive messages to/from a server, and has a pool of /// in-scope entities/components that are synced with the server -#[cfg_attr(feature = "bevy_support", derive(Resource))] pub struct Client { // Config client_config: ClientConfig, diff --git a/server/Cargo.toml b/server/Cargo.toml index 79d335903..2d26fce70 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -17,7 +17,7 @@ edition = "2021" maintenance = { status = "actively-developed" } [features] -bevy_support = ["naia-shared/bevy_support", "bevy_ecs"] +bevy_support = ["naia-shared/bevy_support"] zstd_support = ["naia-shared/zstd_support"] transport_webrtc = [ "naia-server-socket" ] transport_udp = [] @@ -25,7 +25,6 @@ transport_udp = [] [dependencies] naia-shared = { version = "0.22", path = "../shared" } naia-server-socket = { version = "0.22", path = "../socket/server", optional = true } -bevy_ecs = { version = "0.12.1", default_features = false, optional = true } cfg-if = { version = "1.0" } log = { version = "0.4" } ring = { version = "0.16.15" } diff --git a/server/src/server.rs b/server/src/server.rs index 2334b5374..bdb2f0721 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -8,9 +8,6 @@ use std::{ use log::{info, warn}; -#[cfg(feature = "bevy_support")] -use bevy_ecs::prelude::Resource; - use naia_shared::{ BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, @@ -49,7 +46,6 @@ use super::{ /// A server that uses either UDP or WebRTC communication to send/receive /// messages to/from connected clients, and syncs registered entities to /// clients to whom they are in-scope -#[cfg_attr(feature = "bevy_support", derive(Resource))] pub struct Server { // Config server_config: ServerConfig, From cda51a9514f633397aec1db7ca3327eb3edd6445 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 13 Jan 2024 20:10:10 -0600 Subject: [PATCH 09/99] - shared plugin works for multiple Bevy Clients .. still have stuff to fix though --- adapters/bevy/client/src/plugin.rs | 2 +- adapters/bevy/server/src/plugin.rs | 4 +++- adapters/bevy/shared/src/plugin.rs | 19 +++++++++++++++++-- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index 887fc3473..2cecbd7f5 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -59,7 +59,7 @@ impl PluginType for Plugin { app // SHARED PLUGIN // - .add_plugins(SharedPlugin) + .add_plugins(SharedPlugin::::new()) // RESOURCES // .insert_resource(client) // EVENTS // diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index ddaa11522..5330c6547 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -30,6 +30,8 @@ impl PluginConfig { } } +pub struct Singleton; + pub struct Plugin { config: Mutex>, } @@ -56,7 +58,7 @@ impl PluginType for Plugin { app // SHARED PLUGIN // - .add_plugins(SharedPlugin) + .add_plugins(SharedPlugin::::new()) // RESOURCES // .insert_resource(server) // EVENTS // diff --git a/adapters/bevy/shared/src/plugin.rs b/adapters/bevy/shared/src/plugin.rs index 2da316329..6f082fde2 100644 --- a/adapters/bevy/shared/src/plugin.rs +++ b/adapters/bevy/shared/src/plugin.rs @@ -1,16 +1,31 @@ +use std::marker::PhantomData; + use bevy_app::{App, Plugin as PluginType, Update}; use bevy_ecs::schedule::{IntoSystemConfigs, IntoSystemSetConfigs}; +use log::warn; + use crate::{ change_detection::{on_despawn, HostSyncEvent}, system_set::HostSyncChangeTracking, BeforeReceiveEvents, ReceiveEvents, }; -pub struct SharedPlugin; +pub struct SharedPlugin { + phantom_t: PhantomData, +} + +impl SharedPlugin { + pub fn new() -> Self { + Self { + phantom_t: PhantomData, + } + } +} -impl PluginType for SharedPlugin { +impl PluginType for SharedPlugin { fn build(&self, app: &mut App) { + warn!("FIX THIS NOW CONNOR! shouldn't run this plugin twice! inspect app.world to see if this needs to happen!"); app // EVENTS // .add_event::() From fdebbb5ed366252c7acf5eea511aeef57a2f4bd2 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 14 Jan 2024 20:18:23 -0600 Subject: [PATCH 10/99] expose Message type to naia_bevy_client adapter --- adapters/bevy/client/src/lib.rs | 2 +- demos/bevy/server/src/main.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 15f9878f3..e22466400 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -2,7 +2,7 @@ pub use naia_bevy_shared::{ sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, }; pub use naia_client::{ - shared::{Instant, default_channels}, transport, ClientConfig, CommandHistory, ReplicationConfig, + shared::{Message, Instant, default_channels}, transport, ClientConfig, CommandHistory, ReplicationConfig, }; pub mod events; diff --git a/demos/bevy/server/src/main.rs b/demos/bevy/server/src/main.rs index af7cdb2a5..54636fc0c 100644 --- a/demos/bevy/server/src/main.rs +++ b/demos/bevy/server/src/main.rs @@ -1,8 +1,9 @@ +use std::time::Duration; + use bevy_app::{App, ScheduleRunnerPlugin, Startup, Update}; use bevy_core::{FrameCountPlugin, TaskPoolPlugin, TypeRegistrationPlugin}; use bevy_ecs::schedule::IntoSystemConfigs; use bevy_log::{info, LogPlugin}; -use std::time::Duration; use naia_bevy_demo_shared::protocol; use naia_bevy_server::{Plugin as ServerPlugin, ReceiveEvents, ServerConfig}; From 0e9c32c7d537a34c6fefd5e29c43a9c430229e16 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 15 Jan 2024 00:19:54 -0600 Subject: [PATCH 11/99] some progress? --- adapters/bevy/client/src/commands.rs | 4 ++-- adapters/bevy/client/src/components.rs | 2 +- adapters/bevy/client/src/lib.rs | 1 + adapters/bevy/client/src/plugin.rs | 2 +- adapters/bevy/client/src/systems.rs | 4 ++-- adapters/bevy/server/src/commands.rs | 5 +++-- adapters/bevy/server/src/components.rs | 4 +++- adapters/bevy/server/src/plugin.rs | 20 ++++++++++++++++++-- adapters/bevy/server/src/systems.rs | 7 ++++--- adapters/bevy/shared/src/change_detection.rs | 12 ++++++------ adapters/bevy/shared/src/components.rs | 14 +++++++++++++- adapters/bevy/shared/src/lib.rs | 4 ++-- adapters/bevy/shared/src/plugin.rs | 2 +- socket/client/Cargo.toml | 2 +- 14 files changed, 58 insertions(+), 25 deletions(-) diff --git a/adapters/bevy/client/src/commands.rs b/adapters/bevy/client/src/commands.rs index 12fd963bb..18b21c5de 100644 --- a/adapters/bevy/client/src/commands.rs +++ b/adapters/bevy/client/src/commands.rs @@ -38,7 +38,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { client.enable_replication(&self.id()); - self.insert(HostOwned); + self.insert(HostOwned::::new()); return self; } @@ -47,7 +47,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { client: &mut Client, ) -> &'a mut EntityCommands<'w, 's, 'a> { client.disable_replication(&self.id()); - self.remove::(); + self.remove::>(); return self; } diff --git a/adapters/bevy/client/src/components.rs b/adapters/bevy/client/src/components.rs index 3791a2aec..a3661e224 100644 --- a/adapters/bevy/client/src/components.rs +++ b/adapters/bevy/client/src/components.rs @@ -2,7 +2,7 @@ use bevy_ecs::component::Component; use naia_bevy_shared::HostOwned; -pub type ClientOwned = HostOwned; +pub type ClientOwned = HostOwned; #[derive(Component)] pub struct ServerOwned; diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index e22466400..4a796afc7 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -12,6 +12,7 @@ mod commands; mod components; mod plugin; mod systems; +mod protocol; pub use client::Client; pub use commands::CommandsExt; diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index 2cecbd7f5..c499e2871 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -51,7 +51,7 @@ impl PluginType for Plugin { let mut config = self.config.lock().unwrap().deref_mut().take().unwrap(); let world_data = config.protocol.take_world_data(); - world_data.add_systems(app); + world_data.add_systems::(app); app.insert_resource(world_data); let client = Client::::new(config.client_config, config.protocol.into()); diff --git a/adapters/bevy/client/src/systems.rs b/adapters/bevy/client/src/systems.rs index 09e4bae11..37a369c86 100644 --- a/adapters/bevy/client/src/systems.rs +++ b/adapters/bevy/client/src/systems.rs @@ -184,7 +184,7 @@ pub fn before_receive_events(world: &mut World) { } for entity in auth_granted_entities { if world.get_entity(entity).is_some() { - world.entity_mut(entity).insert(HostOwned); + world.entity_mut(entity).insert(HostOwned::::new()); } else { warn!("Granted auth to an entity that no longer exists! {:?}", entity); } @@ -213,7 +213,7 @@ pub fn before_receive_events(world: &mut World) { } for entity in auth_reset_entities { if world.get_entity(entity).is_some() { - world.entity_mut(entity).remove::(); + world.entity_mut(entity).remove::>(); } else { warn!("Reset auth to an entity that no longer exists! {:?}", entity); } diff --git a/adapters/bevy/server/src/commands.rs b/adapters/bevy/server/src/commands.rs index 2e3b730fd..184f3f6ef 100644 --- a/adapters/bevy/server/src/commands.rs +++ b/adapters/bevy/server/src/commands.rs @@ -8,6 +8,7 @@ use naia_bevy_shared::{EntityAuthStatus, HostOwned, WorldProxyMut}; use naia_server::{ReplicationConfig, UserKey}; use crate::{Server, server::ServerWrapper}; +use crate::plugin::Singleton; // Bevy Commands Extension pub trait CommandsExt<'w, 's, 'a> { @@ -33,7 +34,7 @@ pub trait CommandsExt<'w, 's, 'a> { impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn enable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a> { server.enable_replication(&self.id()); - self.insert(HostOwned); + self.insert(HostOwned::::new()); return self; } @@ -42,7 +43,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { server: &mut Server, ) -> &'a mut EntityCommands<'w, 's, 'a> { server.disable_replication(&self.id()); - self.remove::(); + self.remove::>(); return self; } diff --git a/adapters/bevy/server/src/components.rs b/adapters/bevy/server/src/components.rs index 354899dba..0c2a7fd35 100644 --- a/adapters/bevy/server/src/components.rs +++ b/adapters/bevy/server/src/components.rs @@ -3,7 +3,9 @@ use bevy_ecs::component::Component; use naia_bevy_shared::HostOwned; use naia_server::UserKey; -pub type ServerOwned = HostOwned; +use crate::plugin::Singleton; + +pub type ServerOwned = HostOwned; #[derive(Component)] pub struct ClientOwned(pub UserKey); diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index 5330c6547..be545d603 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -3,7 +3,7 @@ use std::{ops::DerefMut, sync::Mutex}; use bevy_app::{App, Plugin as PluginType, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs}; -use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin}; +use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin, HostSyncChangeTracking, AppTag, ComponentAccess}; use naia_server::{Server, ServerConfig}; use super::{ @@ -30,8 +30,24 @@ impl PluginConfig { } } +#[derive(Clone)] pub struct Singleton; +impl AppTag for Singleton { + fn add_systems(boxed_component: Box, app: &mut App) { + boxed_component.add_systems(app); + + // or + + app.add_systems( + Update, + (on_component_added::, on_component_removed::) + .chain() + .in_set(HostSyncChangeTracking), + ); + } +} + pub struct Plugin { config: Mutex>, } @@ -50,7 +66,7 @@ impl PluginType for Plugin { let mut config = self.config.lock().unwrap().deref_mut().take().unwrap(); let world_data = config.protocol.take_world_data(); - world_data.add_systems(app); + world_data.add_systems::(Singleton, app); app.insert_resource(world_data); let server = Server::::new(config.server_config, config.protocol.into()); diff --git a/adapters/bevy/server/src/systems.rs b/adapters/bevy/server/src/systems.rs index a77442215..0bda391fb 100644 --- a/adapters/bevy/server/src/systems.rs +++ b/adapters/bevy/server/src/systems.rs @@ -11,6 +11,7 @@ use naia_bevy_shared::{HostOwned, HostSyncEvent, WorldMutType, WorldProxy, World use naia_server::EntityOwner; use crate::{ClientOwned, EntityAuthStatus, server::ServerWrapper}; +use crate::plugin::Singleton; mod naia_events { pub use naia_server::{ @@ -184,14 +185,14 @@ pub fn before_receive_events(world: &mut World) { // Delegate Entity Event if events.has::() { for (_, entity) in events.read::() { - world.entity_mut(entity).insert(HostOwned); + world.entity_mut(entity).insert(HostOwned::::new()); } } // Entity Auth Given Event if events.has::() { for (_, entity) in events.read::() { - world.entity_mut(entity).remove::(); + world.entity_mut(entity).remove::>(); } } @@ -199,7 +200,7 @@ pub fn before_receive_events(world: &mut World) { if events.has::() { for entity in events.read::() { if let Some(mut entity_mut) = world.get_entity_mut(entity) { - entity_mut.insert(HostOwned); + entity_mut.insert(HostOwned::::new()); } } } diff --git a/adapters/bevy/shared/src/change_detection.rs b/adapters/bevy/shared/src/change_detection.rs index fecdc2b0a..1d0f242ae 100644 --- a/adapters/bevy/shared/src/change_detection.rs +++ b/adapters/bevy/shared/src/change_detection.rs @@ -18,10 +18,10 @@ pub enum HostSyncEvent { Despawn(Entity), } -pub fn on_despawn( +pub fn on_despawn( mut events: EventWriter, query: Query, - mut removals: RemovedComponents, + mut removals: RemovedComponents>, ) { for entity in removals.read() { if let Ok(_) = query.get(entity) { @@ -33,18 +33,18 @@ pub fn on_despawn( } } -pub fn on_component_added( +pub fn on_component_added( mut events: EventWriter, - query: Query, With)>, + query: Query, With>)>, ) { for entity in query.iter() { events.send(HostSyncEvent::Insert(entity, ComponentKind::of::())); } } -pub fn on_component_removed( +pub fn on_component_removed( mut events: EventWriter, - query: Query>, + query: Query>>, mut removals: RemovedComponents, ) { for entity in removals.read() { diff --git a/adapters/bevy/shared/src/components.rs b/adapters/bevy/shared/src/components.rs index 166aed074..e1309b912 100644 --- a/adapters/bevy/shared/src/components.rs +++ b/adapters/bevy/shared/src/components.rs @@ -1,4 +1,16 @@ +use std::marker::PhantomData; + use bevy_ecs::component::Component; #[derive(Component)] -pub struct HostOwned; +pub struct HostOwned { + phantom_t: PhantomData, +} + +impl HostOwned { + pub fn new() -> Self { + Self { + phantom_t: PhantomData, + } + } +} diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index e6469b6c9..0a496275e 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -24,11 +24,11 @@ mod world_data; mod world_proxy; pub use change_detection::HostSyncEvent; -pub use component_access::{ComponentAccess, ComponentAccessor}; +pub use component_access::{ComponentAccess, ComponentAccessor, AppTag}; pub use components::HostOwned; pub use plugin::SharedPlugin; pub use protocol::Protocol; pub use protocol_plugin::ProtocolPlugin; -pub use system_set::{BeforeReceiveEvents, ReceiveEvents}; +pub use system_set::{BeforeReceiveEvents, ReceiveEvents, HostSyncChangeTracking}; pub use world_data::WorldData; pub use world_proxy::{WorldMut, WorldProxy, WorldProxyMut, WorldRef}; diff --git a/adapters/bevy/shared/src/plugin.rs b/adapters/bevy/shared/src/plugin.rs index 6f082fde2..a74ce4921 100644 --- a/adapters/bevy/shared/src/plugin.rs +++ b/adapters/bevy/shared/src/plugin.rs @@ -33,6 +33,6 @@ impl PluginType for SharedPlugin { .configure_sets(Update, HostSyncChangeTracking.before(BeforeReceiveEvents)) .configure_sets(Update, BeforeReceiveEvents.before(ReceiveEvents)) // SYSTEMS // - .add_systems(Update, on_despawn.in_set(HostSyncChangeTracking)); + .add_systems(Update, on_despawn::.in_set(HostSyncChangeTracking)); } } diff --git a/socket/client/Cargo.toml b/socket/client/Cargo.toml index 50424afe8..c70c8559b 100644 --- a/socket/client/Cargo.toml +++ b/socket/client/Cargo.toml @@ -34,7 +34,7 @@ tinyjson = { version = "2.3", optional = true } miniquad = { version = "0.3", features = ["log-impl"], optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -webrtc-unreliable-client = { version = "0.2" } +webrtc-unreliable-client = { path = "../../../webrtc-unreliable-client/client" } tokio = { version = "1.15", features = ["full"] } once_cell = { version = "1.4.1" } From 7176e9482b9acc152ab3c213a6c725e9bc73b456 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 15 Jan 2024 08:44:10 -0600 Subject: [PATCH 12/99] attempting to handle components across multi clients --- adapters/bevy/client/src/commands.rs | 7 ++- adapters/bevy/client/src/components.rs | 2 +- adapters/bevy/client/src/lib.rs | 1 - adapters/bevy/client/src/plugin.rs | 9 ++- adapters/bevy/client/src/systems.rs | 29 ++++++++-- adapters/bevy/server/src/commands.rs | 4 +- adapters/bevy/server/src/components.rs | 2 +- adapters/bevy/server/src/plugin.rs | 17 +----- adapters/bevy/server/src/systems.rs | 12 ++-- adapters/bevy/shared/src/change_detection.rs | 59 ++++++++++++++------ adapters/bevy/shared/src/component_access.rs | 18 ++++-- adapters/bevy/shared/src/components.rs | 44 ++++++++++++--- adapters/bevy/shared/src/lib.rs | 2 +- adapters/bevy/shared/src/plugin.rs | 10 +++- adapters/bevy/shared/src/system_set.rs | 3 + adapters/bevy/shared/src/world_data.rs | 11 +++- 16 files changed, 159 insertions(+), 71 deletions(-) diff --git a/adapters/bevy/client/src/commands.rs b/adapters/bevy/client/src/commands.rs index 18b21c5de..26bea6210 100644 --- a/adapters/bevy/client/src/commands.rs +++ b/adapters/bevy/client/src/commands.rs @@ -1,4 +1,5 @@ -use std::marker::PhantomData; +use std::{any::Any, marker::PhantomData}; + use bevy_ecs::{ entity::Entity, system::{Command as BevyCommand, EntityCommands}, @@ -38,7 +39,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { client.enable_replication(&self.id()); - self.insert(HostOwned::::new()); + self.insert(HostOwned::new::()); return self; } @@ -47,7 +48,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { client: &mut Client, ) -> &'a mut EntityCommands<'w, 's, 'a> { client.disable_replication(&self.id()); - self.remove::>(); + self.remove::(); return self; } diff --git a/adapters/bevy/client/src/components.rs b/adapters/bevy/client/src/components.rs index a3661e224..3791a2aec 100644 --- a/adapters/bevy/client/src/components.rs +++ b/adapters/bevy/client/src/components.rs @@ -2,7 +2,7 @@ use bevy_ecs::component::Component; use naia_bevy_shared::HostOwned; -pub type ClientOwned = HostOwned; +pub type ClientOwned = HostOwned; #[derive(Component)] pub struct ServerOwned; diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 4a796afc7..e22466400 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -12,7 +12,6 @@ mod commands; mod components; mod plugin; mod systems; -mod protocol; pub use client::Client; pub use commands::CommandsExt; diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index c499e2871..9ef0fdd89 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -3,7 +3,7 @@ use std::{marker::PhantomData, ops::DerefMut, sync::Mutex}; use bevy_app::{App, Plugin as PluginType, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs}; -use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin}; +use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin, WorldData}; use naia_client::{Client, ClientConfig}; use super::{ @@ -50,8 +50,13 @@ impl PluginType for Plugin { fn build(&self, app: &mut App) { let mut config = self.config.lock().unwrap().deref_mut().take().unwrap(); - let world_data = config.protocol.take_world_data(); + let mut world_data = config.protocol.take_world_data(); world_data.add_systems::(app); + + if let Some(old_world_data) = app.world.remove_resource::() { + world_data.merge(old_world_data); + } + app.insert_resource(world_data); let client = Client::::new(config.client_config, config.protocol.into()); diff --git a/adapters/bevy/client/src/systems.rs b/adapters/bevy/client/src/systems.rs index 37a369c86..29db24918 100644 --- a/adapters/bevy/client/src/systems.rs +++ b/adapters/bevy/client/src/systems.rs @@ -1,3 +1,4 @@ +use std::any::TypeId; use std::ops::DerefMut; use log::warn; @@ -29,31 +30,49 @@ mod bevy_events { use crate::{ServerOwned, client::ClientWrapper}; pub fn before_receive_events(world: &mut World) { + + let host_id = TypeId::of::(); + world.resource_scope(|world, mut client: Mut>| { // Host Component Updates + let mut other_host_component_events = Vec::new(); let mut host_component_event_reader = world .get_resource_mut::>() .unwrap(); let host_component_events: Vec = host_component_event_reader.drain().collect(); for event in host_component_events { + if event.host_id() != host_id { + other_host_component_events.push(event); + continue; + } match event { - HostSyncEvent::Insert(entity, component_kind) => { + HostSyncEvent::Insert(_, entity, component_kind) => { let mut world_proxy = world.proxy_mut(); let Some(mut component_mut) = world_proxy.component_mut_of_kind(&entity, &component_kind) else { continue; }; client.client.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); } - HostSyncEvent::Remove(entity, component_kind) => { + HostSyncEvent::Remove(_, entity, component_kind) => { client.client.remove_component_worldless(&entity, &component_kind); } - HostSyncEvent::Despawn(entity) => { + HostSyncEvent::Despawn(_, entity) => { client.client.despawn_entity_worldless(&entity); } } } + // pass non-matching host component events to be handled elsewhere + if !other_host_component_events.is_empty() { + let mut event_writer = world + .get_resource_mut::>() + .unwrap(); + for event in other_host_component_events { + event_writer.send(event); + } + } + // Receive Events let mut events = client.client.receive(world.proxy_mut()); if !events.is_empty() { @@ -184,7 +203,7 @@ pub fn before_receive_events(world: &mut World) { } for entity in auth_granted_entities { if world.get_entity(entity).is_some() { - world.entity_mut(entity).insert(HostOwned::::new()); + world.entity_mut(entity).insert(HostOwned::new::()); } else { warn!("Granted auth to an entity that no longer exists! {:?}", entity); } @@ -213,7 +232,7 @@ pub fn before_receive_events(world: &mut World) { } for entity in auth_reset_entities { if world.get_entity(entity).is_some() { - world.entity_mut(entity).remove::>(); + world.entity_mut(entity).remove::(); } else { warn!("Reset auth to an entity that no longer exists! {:?}", entity); } diff --git a/adapters/bevy/server/src/commands.rs b/adapters/bevy/server/src/commands.rs index 184f3f6ef..bd0001e63 100644 --- a/adapters/bevy/server/src/commands.rs +++ b/adapters/bevy/server/src/commands.rs @@ -34,7 +34,7 @@ pub trait CommandsExt<'w, 's, 'a> { impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn enable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a> { server.enable_replication(&self.id()); - self.insert(HostOwned::::new()); + self.insert(HostOwned::new::()); return self; } @@ -43,7 +43,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { server: &mut Server, ) -> &'a mut EntityCommands<'w, 's, 'a> { server.disable_replication(&self.id()); - self.remove::>(); + self.remove::(); return self; } diff --git a/adapters/bevy/server/src/components.rs b/adapters/bevy/server/src/components.rs index 0c2a7fd35..9d2a11351 100644 --- a/adapters/bevy/server/src/components.rs +++ b/adapters/bevy/server/src/components.rs @@ -5,7 +5,7 @@ use naia_server::UserKey; use crate::plugin::Singleton; -pub type ServerOwned = HostOwned; +pub type ServerOwned = HostOwned; #[derive(Component)] pub struct ClientOwned(pub UserKey); diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index be545d603..58ed14b7b 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -33,21 +33,6 @@ impl PluginConfig { #[derive(Clone)] pub struct Singleton; -impl AppTag for Singleton { - fn add_systems(boxed_component: Box, app: &mut App) { - boxed_component.add_systems(app); - - // or - - app.add_systems( - Update, - (on_component_added::, on_component_removed::) - .chain() - .in_set(HostSyncChangeTracking), - ); - } -} - pub struct Plugin { config: Mutex>, } @@ -66,7 +51,7 @@ impl PluginType for Plugin { let mut config = self.config.lock().unwrap().deref_mut().take().unwrap(); let world_data = config.protocol.take_world_data(); - world_data.add_systems::(Singleton, app); + world_data.add_systems::(app); app.insert_resource(world_data); let server = Server::::new(config.server_config, config.protocol.into()); diff --git a/adapters/bevy/server/src/systems.rs b/adapters/bevy/server/src/systems.rs index 0bda391fb..470f706d4 100644 --- a/adapters/bevy/server/src/systems.rs +++ b/adapters/bevy/server/src/systems.rs @@ -43,7 +43,7 @@ pub fn before_receive_events(world: &mut World) { let host_component_events: Vec = host_component_event_reader.drain().collect(); for event in host_component_events { match event { - HostSyncEvent::Insert(entity, component_kind) => { + HostSyncEvent::Insert(host_id, entity, component_kind) => { if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; @@ -55,14 +55,14 @@ pub fn before_receive_events(world: &mut World) { }; server.0.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); } - HostSyncEvent::Remove(entity, component_kind) => { + HostSyncEvent::Remove(host_id, entity, component_kind) => { if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; } server.0.remove_component_worldless(&entity, &component_kind); } - HostSyncEvent::Despawn(entity) => { + HostSyncEvent::Despawn(host_id, entity) => { if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; @@ -185,14 +185,14 @@ pub fn before_receive_events(world: &mut World) { // Delegate Entity Event if events.has::() { for (_, entity) in events.read::() { - world.entity_mut(entity).insert(HostOwned::::new()); + world.entity_mut(entity).insert(HostOwned::new::()); } } // Entity Auth Given Event if events.has::() { for (_, entity) in events.read::() { - world.entity_mut(entity).remove::>(); + world.entity_mut(entity).remove::(); } } @@ -200,7 +200,7 @@ pub fn before_receive_events(world: &mut World) { if events.has::() { for entity in events.read::() { if let Some(mut entity_mut) = world.get_entity_mut(entity) { - entity_mut.insert(HostOwned::::new()); + entity_mut.insert(HostOwned::new::()); } } } diff --git a/adapters/bevy/shared/src/change_detection.rs b/adapters/bevy/shared/src/change_detection.rs index 1d0f242ae..0c28ae173 100644 --- a/adapters/bevy/shared/src/change_detection.rs +++ b/adapters/bevy/shared/src/change_detection.rs @@ -1,55 +1,80 @@ +use std::any::TypeId; + use bevy_ecs::{ entity::Entity, event::EventWriter, prelude::Event, - query::{Added, With}, + query::{Added, With, Changed}, removal_detection::RemovedComponents, - system::Query, + system::{Query, ResMut}, }; use naia_shared::{ComponentKind, Replicate}; -use crate::HostOwned; +use crate::{HostOwned, HostOwnedMap}; #[derive(Event)] pub enum HostSyncEvent { - Insert(Entity, ComponentKind), - Remove(Entity, ComponentKind), - Despawn(Entity), + Insert(TypeId, Entity, ComponentKind), + Remove(TypeId, Entity, ComponentKind), + Despawn(TypeId, Entity), +} + +impl HostSyncEvent { + pub fn host_id(&self) -> TypeId { + match self { + HostSyncEvent::Insert(type_id, _, _) => *type_id, + HostSyncEvent::Remove(type_id, _, _) => *type_id, + HostSyncEvent::Despawn(type_id, _) => *type_id, + } + } } -pub fn on_despawn( +pub fn on_host_owned_added( + query: Query<(Entity, &HostOwned), Changed>, + mut host_owned_map: ResMut, +) { + for (entity, host_owned) in query.iter() { + host_owned_map.insert(entity, *host_owned); + } +} + +pub fn on_despawn( mut events: EventWriter, query: Query, - mut removals: RemovedComponents>, + mut removals: RemovedComponents, + mut host_owned_map: ResMut, ) { for entity in removals.read() { if let Ok(_) = query.get(entity) { // Entity is still alive, expected if Auth is reset on Delegated Entity } else { // info!("despawn on HostOwned entity: {:?}", entity); - events.send(HostSyncEvent::Despawn(entity)); + let Some(host_owned) = host_owned_map.remove(&entity) else { + panic!("HostOwned entity {:?} not found in HostOwnedMap", entity); + }; + events.send(HostSyncEvent::Despawn(host_owned.type_id(), entity)); } } } -pub fn on_component_added( +pub fn on_component_added( mut events: EventWriter, - query: Query, With>)>, + query: Query<(Entity, &HostOwned), Added>, ) { - for entity in query.iter() { - events.send(HostSyncEvent::Insert(entity, ComponentKind::of::())); + for (entity, host_owned) in query.iter() { + events.send(HostSyncEvent::Insert(host_owned.type_id(), entity, ComponentKind::of::())); } } -pub fn on_component_removed( +pub fn on_component_removed( mut events: EventWriter, - query: Query>>, + query: Query<&HostOwned>, mut removals: RemovedComponents, ) { for entity in removals.read() { - if let Ok(_) = query.get(entity) { - events.send(HostSyncEvent::Remove(entity, ComponentKind::of::())); + if let Ok(host_owned) = query.get(entity) { + events.send(HostSyncEvent::Remove(host_owned.type_id(), entity, ComponentKind::of::())); } } } diff --git a/adapters/bevy/shared/src/component_access.rs b/adapters/bevy/shared/src/component_access.rs index fa1b9b1a2..059f4e9a8 100644 --- a/adapters/bevy/shared/src/component_access.rs +++ b/adapters/bevy/shared/src/component_access.rs @@ -1,9 +1,10 @@ use std::{any::Any, marker::PhantomData}; +use std::any::TypeId; use bevy_app::{App, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs, world::World}; -use naia_shared::{GlobalWorldManagerType, ReplicaDynMutWrapper, ReplicaDynRefWrapper, Replicate}; +use naia_shared::{ComponentKind, GlobalWorldManagerType, ReplicaDynMutWrapper, ReplicaDynRefWrapper, Replicate}; use super::{ change_detection::{on_component_added, on_component_removed}, @@ -11,6 +12,10 @@ use super::{ system_set::HostSyncChangeTracking, }; +pub trait AppTag: Send + Sync + 'static { + fn add_systems(boxed_component: Box, app: &mut App); +} + pub trait ComponentAccess: Send + Sync { fn add_systems(&self, app: &mut App); fn box_clone(&self) -> Box; @@ -54,10 +59,15 @@ pub struct ComponentAccessor { } impl ComponentAccessor { - pub fn create() -> Box { - let inner_box: Box = Box::new(ComponentAccessor { + + fn new() -> Self { + Self { phantom_r: PhantomData::, - }); + } + } + + pub fn create() -> Box { + let inner_box: Box = Box::new(ComponentAccessor::::new()); Box::new(inner_box) } } diff --git a/adapters/bevy/shared/src/components.rs b/adapters/bevy/shared/src/components.rs index e1309b912..e1e9c3ab3 100644 --- a/adapters/bevy/shared/src/components.rs +++ b/adapters/bevy/shared/src/components.rs @@ -1,16 +1,44 @@ -use std::marker::PhantomData; +use std::any::{Any, TypeId}; +use std::collections::HashMap; -use bevy_ecs::component::Component; +use bevy_ecs::{entity::Entity, component::Component, system::Resource}; -#[derive(Component)] -pub struct HostOwned { - phantom_t: PhantomData, +#[derive(Component, Clone, Copy)] +pub struct HostOwned { + type_id: TypeId } -impl HostOwned { - pub fn new() -> Self { +impl HostOwned { + pub fn new() -> Self { Self { - phantom_t: PhantomData, + type_id: TypeId::of::() } } + + pub fn type_id(&self) -> TypeId { + self.type_id + } +} + +#[derive(Resource)] +pub struct HostOwnedMap { + map: HashMap, } + +impl Default for HostOwnedMap { + fn default() -> Self { + Self { + map: HashMap::new(), + } + } +} + +impl HostOwnedMap { + pub fn insert(&mut self, entity: Entity, host_owned: HostOwned) { + self.map.insert(entity, host_owned); + } + + pub fn remove(&mut self, entity: &Entity) -> Option { + self.map.remove(entity) + } +} \ No newline at end of file diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 0a496275e..f81c0c85f 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -25,7 +25,7 @@ mod world_proxy; pub use change_detection::HostSyncEvent; pub use component_access::{ComponentAccess, ComponentAccessor, AppTag}; -pub use components::HostOwned; +pub use components::{HostOwned, HostOwnedMap}; pub use plugin::SharedPlugin; pub use protocol::Protocol; pub use protocol_plugin::ProtocolPlugin; diff --git a/adapters/bevy/shared/src/plugin.rs b/adapters/bevy/shared/src/plugin.rs index a74ce4921..de549c9cf 100644 --- a/adapters/bevy/shared/src/plugin.rs +++ b/adapters/bevy/shared/src/plugin.rs @@ -7,9 +7,11 @@ use log::warn; use crate::{ change_detection::{on_despawn, HostSyncEvent}, - system_set::HostSyncChangeTracking, + system_set::{HostSyncChangeTracking, BeforeHostSyncChangeTracking}, BeforeReceiveEvents, ReceiveEvents, + HostOwnedMap, }; +use crate::change_detection::on_host_owned_added; pub struct SharedPlugin { phantom_t: PhantomData, @@ -27,12 +29,16 @@ impl PluginType for SharedPlugin { fn build(&self, app: &mut App) { warn!("FIX THIS NOW CONNOR! shouldn't run this plugin twice! inspect app.world to see if this needs to happen!"); app + // RESOURCES // + .init_resource::() // EVENTS // .add_event::() // SYSTEM SETS // + .configure_sets(Update, BeforeHostSyncChangeTracking.before(HostSyncChangeTracking)) .configure_sets(Update, HostSyncChangeTracking.before(BeforeReceiveEvents)) .configure_sets(Update, BeforeReceiveEvents.before(ReceiveEvents)) // SYSTEMS // - .add_systems(Update, on_despawn::.in_set(HostSyncChangeTracking)); + .add_systems(Update, on_host_owned_added.in_set(BeforeHostSyncChangeTracking)) + .add_systems(Update, on_despawn.in_set(HostSyncChangeTracking)); } } diff --git a/adapters/bevy/shared/src/system_set.rs b/adapters/bevy/shared/src/system_set.rs index b5c8364f0..8a59a4495 100644 --- a/adapters/bevy/shared/src/system_set.rs +++ b/adapters/bevy/shared/src/system_set.rs @@ -8,3 +8,6 @@ pub struct BeforeReceiveEvents; #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] pub struct HostSyncChangeTracking; + +#[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] +pub struct BeforeHostSyncChangeTracking; diff --git a/adapters/bevy/shared/src/world_data.rs b/adapters/bevy/shared/src/world_data.rs index e311419a5..f97ac6838 100644 --- a/adapters/bevy/shared/src/world_data.rs +++ b/adapters/bevy/shared/src/world_data.rs @@ -13,7 +13,7 @@ use bevy_ecs::{ use naia_shared::{ComponentKind, Replicate}; -use super::component_access::{ComponentAccess, ComponentAccessor}; +use super::component_access::{ComponentAccess, ComponentAccessor, AppTag}; #[derive(Resource)] pub struct WorldData { @@ -41,7 +41,14 @@ impl WorldData { } } - pub fn add_systems(&self, app: &mut App) { + pub fn merge(&mut self, other: Self) { + if !self.entities.is_empty() || !other.entities.is_empty() { + panic!("merging world data with non-empty entities"); + } + self.kind_to_accessor_map.extend(other.kind_to_accessor_map); + } + + pub fn add_systems(&self, app: &mut App) { for (_kind, accessor_any) in &self.kind_to_accessor_map { let accessor = accessor_any .downcast_ref::>() From 50640d04ec057ac38c530484dce2036342f3cefd Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 16 Jan 2024 18:02:43 -0600 Subject: [PATCH 13/99] cargo fmt --- adapters/bevy/client/src/client.rs | 13 ++-- adapters/bevy/client/src/commands.rs | 72 ++++++++++++++----- adapters/bevy/client/src/events.rs | 15 +++- adapters/bevy/client/src/lib.rs | 3 +- adapters/bevy/client/src/plugin.rs | 7 +- adapters/bevy/client/src/systems.rs | 3 +- adapters/bevy/server/src/commands.rs | 8 ++- adapters/bevy/server/src/components.rs | 2 - adapters/bevy/server/src/lib.rs | 5 +- adapters/bevy/server/src/plugin.rs | 4 +- adapters/bevy/server/src/server.rs | 3 +- adapters/bevy/server/src/systems.rs | 8 +-- adapters/bevy/shared/src/change_detection.rs | 14 +++- adapters/bevy/shared/src/component_access.rs | 4 +- adapters/bevy/shared/src/components.rs | 8 +-- adapters/bevy/shared/src/lib.rs | 4 +- adapters/bevy/shared/src/plugin.rs | 17 +++-- adapters/bevy/shared/src/world_data.rs | 2 +- adapters/hecs/shared/src/lib.rs | 14 ++-- adapters/hecs/shared/src/world_proxy.rs | 32 +++++++-- adapters/hecs/shared/src/world_wrapper.rs | 32 +++++++-- client/src/client.rs | 2 +- client/src/lib.rs | 3 +- demos/basic/client/app/src/app.rs | 8 ++- demos/demo_utils/demo_world/src/world.rs | 32 +++++++-- shared/src/lib.rs | 2 +- .../src/backends/miniquad/packet_sender.rs | 4 +- .../src/backends/native/packet_sender.rs | 12 ++-- socket/client/src/backends/native/socket.rs | 6 +- 29 files changed, 246 insertions(+), 93 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 860e699cd..54ab1842f 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -1,15 +1,18 @@ -use std::{net::SocketAddr, marker::PhantomData}; +use std::{marker::PhantomData, net::SocketAddr}; use bevy_ecs::{ entity::Entity, - system::{Resource, ResMut, SystemParam}, + system::{ResMut, Resource, SystemParam}, }; use naia_bevy_shared::{ Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, GlobalEntity, Message, Tick, }; -use naia_client::{shared::SocketConfig, transport::Socket, Client as NaiaClient, NaiaClientError, ConnectionStatus}; +use naia_client::{ + shared::SocketConfig, transport::Socket, Client as NaiaClient, ConnectionStatus, + NaiaClientError, +}; use crate::ReplicationConfig; @@ -78,7 +81,9 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { } pub fn send_tick_buffer_message(&mut self, tick: &Tick, message: &M) { - self.client.client.send_tick_buffer_message::(tick, message); + self.client + .client + .send_tick_buffer_message::(tick, message); } //// Ticks //// diff --git a/adapters/bevy/client/src/commands.rs b/adapters/bevy/client/src/commands.rs index 26bea6210..797abdf06 100644 --- a/adapters/bevy/client/src/commands.rs +++ b/adapters/bevy/client/src/commands.rs @@ -1,4 +1,4 @@ -use std::{any::Any, marker::PhantomData}; +use std::marker::PhantomData; use bevy_ecs::{ entity::Entity, @@ -9,7 +9,7 @@ use bevy_ecs::{ use naia_bevy_shared::{EntityAuthStatus, HostOwned, WorldMutType, WorldProxyMut}; use naia_client::ReplicationConfig; -use crate::{Client, client::ClientWrapper}; +use crate::{client::ClientWrapper, Client}; // Bevy Commands Extension pub trait CommandsExt<'w, 's, 'a> { @@ -18,13 +18,30 @@ pub trait CommandsExt<'w, 's, 'a> { &'a mut self, config: ReplicationConfig, ) -> &'a mut EntityCommands<'w, 's, 'a>; - fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; - fn disable_replication(&'a mut self, client: &mut Client) - -> &'a mut EntityCommands<'w, 's, 'a>; - fn replication_config(&'a self, client: &Client) -> Option; - fn request_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; - fn release_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a>; - fn authority(&'a self, client: &Client) -> Option; + fn enable_replication( + &'a mut self, + client: &mut Client, + ) -> &'a mut EntityCommands<'w, 's, 'a>; + fn disable_replication( + &'a mut self, + client: &mut Client, + ) -> &'a mut EntityCommands<'w, 's, 'a>; + fn replication_config( + &'a self, + client: &Client, + ) -> Option; + fn request_authority( + &'a mut self, + client: &mut Client, + ) -> &'a mut EntityCommands<'w, 's, 'a>; + fn release_authority( + &'a mut self, + client: &mut Client, + ) -> &'a mut EntityCommands<'w, 's, 'a>; + fn authority( + &'a self, + client: &Client, + ) -> Option; } impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { @@ -37,7 +54,10 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { commands.entity(new_entity) } - fn enable_replication(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { + fn enable_replication( + &'a mut self, + client: &mut Client, + ) -> &'a mut EntityCommands<'w, 's, 'a> { client.enable_replication(&self.id()); self.insert(HostOwned::new::()); return self; @@ -63,21 +83,33 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { return self; } - fn replication_config(&'a self, client: &Client) -> Option { + fn replication_config( + &'a self, + client: &Client, + ) -> Option { client.replication_config(&self.id()) } - fn request_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { + fn request_authority( + &'a mut self, + client: &mut Client, + ) -> &'a mut EntityCommands<'w, 's, 'a> { client.entity_request_authority(&self.id()); return self; } - fn release_authority(&'a mut self, client: &mut Client) -> &'a mut EntityCommands<'w, 's, 'a> { + fn release_authority( + &'a mut self, + client: &mut Client, + ) -> &'a mut EntityCommands<'w, 's, 'a> { client.entity_release_authority(&self.id()); return self; } - fn authority(&'a self, client: &Client) -> Option { + fn authority( + &'a self, + client: &Client, + ) -> Option { client.entity_authority_status(&self.id()) } } @@ -116,14 +148,22 @@ pub(crate) struct ConfigureReplicationCommand { impl ConfigureReplicationCommand { pub fn new(entity: Entity, config: ReplicationConfig) -> Self { - Self { entity, config, phantom_t: PhantomData } + Self { + entity, + config, + phantom_t: PhantomData, + } } } impl BevyCommand for ConfigureReplicationCommand { fn apply(self, world: &mut World) { world.resource_scope(|world, mut client: Mut>| { - client.client.configure_entity_replication(&mut world.proxy_mut(), &self.entity, self.config); + client.client.configure_entity_replication( + &mut world.proxy_mut(), + &self.entity, + self.config, + ); }); } } diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 9b3b1d57f..48eb7a2b6 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -258,7 +258,10 @@ pub struct InsertComponentEvents { impl InsertComponentEvents { pub fn new(inner: HashMap>) -> Self { - Self { inner, phantom_t: PhantomData } + Self { + inner, + phantom_t: PhantomData, + } } pub fn read(&self) -> Vec { let component_kind = ComponentKind::of::(); @@ -279,7 +282,10 @@ pub struct UpdateComponentEvents { impl UpdateComponentEvents { pub fn new(inner: HashMap>) -> Self { - Self { inner, phantom_t: PhantomData } + Self { + inner, + phantom_t: PhantomData, + } } pub fn read(&self) -> Vec<(Tick, Entity)> { @@ -301,7 +307,10 @@ pub struct RemoveComponentEvents { impl RemoveComponentEvents { pub fn new(inner: HashMap)>>) -> Self { - Self { inner, phantom_t: PhantomData } + Self { + inner, + phantom_t: PhantomData, + } } pub fn clone_new(&self) -> Self { diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index e22466400..d638be1e9 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -2,7 +2,8 @@ pub use naia_bevy_shared::{ sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, }; pub use naia_client::{ - shared::{Message, Instant, default_channels}, transport, ClientConfig, CommandHistory, ReplicationConfig, + shared::{default_channels, Instant, Message}, + transport, ClientConfig, CommandHistory, ReplicationConfig, }; pub mod events; diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index 9ef0fdd89..99a6bd52f 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -7,6 +7,7 @@ use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin, WorldData}; use naia_client::{Client, ClientConfig}; use super::{ + client::ClientWrapper, events::{ ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, EntityAuthDeniedEvent, EntityAuthGrantedEvent, EntityAuthResetEvent, ErrorEvent, InsertComponentEvents, @@ -14,7 +15,6 @@ use super::{ SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvents, }, systems::before_receive_events, - client::ClientWrapper, }; struct PluginConfig { @@ -86,6 +86,9 @@ impl PluginType for Plugin { .add_event::>() .add_event::>() // SYSTEMS // - .add_systems(Update, before_receive_events::.in_set(BeforeReceiveEvents)); + .add_systems( + Update, + before_receive_events::.in_set(BeforeReceiveEvents), + ); } } diff --git a/adapters/bevy/client/src/systems.rs b/adapters/bevy/client/src/systems.rs index 29db24918..abd72ea6c 100644 --- a/adapters/bevy/client/src/systems.rs +++ b/adapters/bevy/client/src/systems.rs @@ -27,10 +27,9 @@ mod bevy_events { }; } -use crate::{ServerOwned, client::ClientWrapper}; +use crate::{client::ClientWrapper, ServerOwned}; pub fn before_receive_events(world: &mut World) { - let host_id = TypeId::of::(); world.resource_scope(|world, mut client: Mut>| { diff --git a/adapters/bevy/server/src/commands.rs b/adapters/bevy/server/src/commands.rs index bd0001e63..1b2f3e5fd 100644 --- a/adapters/bevy/server/src/commands.rs +++ b/adapters/bevy/server/src/commands.rs @@ -7,8 +7,8 @@ use bevy_ecs::{ use naia_bevy_shared::{EntityAuthStatus, HostOwned, WorldProxyMut}; use naia_server::{ReplicationConfig, UserKey}; -use crate::{Server, server::ServerWrapper}; use crate::plugin::Singleton; +use crate::{server::ServerWrapper, Server}; // Bevy Commands Extension pub trait CommandsExt<'w, 's, 'a> { @@ -105,7 +105,11 @@ impl ConfigureReplicationCommand { impl BevyCommand for ConfigureReplicationCommand { fn apply(self, world: &mut World) { world.resource_scope(|world, mut server: Mut| { - server.0.configure_entity_replication(&mut world.proxy_mut(), &self.entity, self.config); + server.0.configure_entity_replication( + &mut world.proxy_mut(), + &self.entity, + self.config, + ); }); } } diff --git a/adapters/bevy/server/src/components.rs b/adapters/bevy/server/src/components.rs index 9d2a11351..354899dba 100644 --- a/adapters/bevy/server/src/components.rs +++ b/adapters/bevy/server/src/components.rs @@ -3,8 +3,6 @@ use bevy_ecs::component::Component; use naia_bevy_shared::HostOwned; use naia_server::UserKey; -use crate::plugin::Singleton; - pub type ServerOwned = HostOwned; #[derive(Component)] diff --git a/adapters/bevy/server/src/lib.rs b/adapters/bevy/server/src/lib.rs index 0e2204f82..9eba5c7bb 100644 --- a/adapters/bevy/server/src/lib.rs +++ b/adapters/bevy/server/src/lib.rs @@ -1,8 +1,9 @@ pub use naia_bevy_shared::{EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick}; pub use naia_server::{ shared::{ - BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, SerdeErr, - SignedInteger, SignedVariableInteger, UnsignedInteger, UnsignedVariableInteger, default_channels, + default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, + FileBitWriter, SerdeErr, SignedInteger, SignedVariableInteger, UnsignedInteger, + UnsignedVariableInteger, }, transport, ReplicationConfig, RoomKey, SerdeBevy as Serde, ServerConfig, UserKey, }; diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index 58ed14b7b..745553a8c 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -3,7 +3,7 @@ use std::{ops::DerefMut, sync::Mutex}; use bevy_app::{App, Plugin as PluginType, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs}; -use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin, HostSyncChangeTracking, AppTag, ComponentAccess}; +use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin}; use naia_server::{Server, ServerConfig}; use super::{ @@ -12,8 +12,8 @@ use super::{ InsertComponentEvents, MessageEvents, PublishEntityEvent, RemoveComponentEvents, SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, }, - systems::before_receive_events, server::ServerWrapper, + systems::before_receive_events, }; struct PluginConfig { diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index fff8453bb..cb466c957 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -1,11 +1,10 @@ - use std::time::Duration; +use bevy_ecs::prelude::Resource; use bevy_ecs::{ entity::Entity, system::{ResMut, SystemParam}, }; -use bevy_ecs::prelude::Resource; use naia_server::{ shared::SocketConfig, transport::Socket, ReplicationConfig, RoomKey, RoomMut, RoomRef, diff --git a/adapters/bevy/server/src/systems.rs b/adapters/bevy/server/src/systems.rs index 470f706d4..ab35bdcb4 100644 --- a/adapters/bevy/server/src/systems.rs +++ b/adapters/bevy/server/src/systems.rs @@ -10,8 +10,8 @@ use log::warn; use naia_bevy_shared::{HostOwned, HostSyncEvent, WorldMutType, WorldProxy, WorldProxyMut}; use naia_server::EntityOwner; -use crate::{ClientOwned, EntityAuthStatus, server::ServerWrapper}; use crate::plugin::Singleton; +use crate::{server::ServerWrapper, ClientOwned, EntityAuthStatus}; mod naia_events { pub use naia_server::{ @@ -43,7 +43,7 @@ pub fn before_receive_events(world: &mut World) { let host_component_events: Vec = host_component_event_reader.drain().collect(); for event in host_component_events { match event { - HostSyncEvent::Insert(host_id, entity, component_kind) => { + HostSyncEvent::Insert(_host_id, entity, component_kind) => { if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; @@ -55,14 +55,14 @@ pub fn before_receive_events(world: &mut World) { }; server.0.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); } - HostSyncEvent::Remove(host_id, entity, component_kind) => { + HostSyncEvent::Remove(_host_id, entity, component_kind) => { if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; } server.0.remove_component_worldless(&entity, &component_kind); } - HostSyncEvent::Despawn(host_id, entity) => { + HostSyncEvent::Despawn(_host_id, entity) => { if server.0.entity_authority_status(&entity) == Some(EntityAuthStatus::Denied) { // if auth status is denied, that means the client is performing this operation and it's already being handled continue; diff --git a/adapters/bevy/shared/src/change_detection.rs b/adapters/bevy/shared/src/change_detection.rs index 0c28ae173..9b783fcc6 100644 --- a/adapters/bevy/shared/src/change_detection.rs +++ b/adapters/bevy/shared/src/change_detection.rs @@ -4,7 +4,7 @@ use bevy_ecs::{ entity::Entity, event::EventWriter, prelude::Event, - query::{Added, With, Changed}, + query::{Added, Changed}, removal_detection::RemovedComponents, system::{Query, ResMut}, }; @@ -63,7 +63,11 @@ pub fn on_component_added( query: Query<(Entity, &HostOwned), Added>, ) { for (entity, host_owned) in query.iter() { - events.send(HostSyncEvent::Insert(host_owned.type_id(), entity, ComponentKind::of::())); + events.send(HostSyncEvent::Insert( + host_owned.type_id(), + entity, + ComponentKind::of::(), + )); } } @@ -74,7 +78,11 @@ pub fn on_component_removed( ) { for entity in removals.read() { if let Ok(host_owned) = query.get(entity) { - events.send(HostSyncEvent::Remove(host_owned.type_id(), entity, ComponentKind::of::())); + events.send(HostSyncEvent::Remove( + host_owned.type_id(), + entity, + ComponentKind::of::(), + )); } } } diff --git a/adapters/bevy/shared/src/component_access.rs b/adapters/bevy/shared/src/component_access.rs index 059f4e9a8..924560be5 100644 --- a/adapters/bevy/shared/src/component_access.rs +++ b/adapters/bevy/shared/src/component_access.rs @@ -1,10 +1,9 @@ use std::{any::Any, marker::PhantomData}; -use std::any::TypeId; use bevy_app::{App, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs, world::World}; -use naia_shared::{ComponentKind, GlobalWorldManagerType, ReplicaDynMutWrapper, ReplicaDynRefWrapper, Replicate}; +use naia_shared::{GlobalWorldManagerType, ReplicaDynMutWrapper, ReplicaDynRefWrapper, Replicate}; use super::{ change_detection::{on_component_added, on_component_removed}, @@ -59,7 +58,6 @@ pub struct ComponentAccessor { } impl ComponentAccessor { - fn new() -> Self { Self { phantom_r: PhantomData::, diff --git a/adapters/bevy/shared/src/components.rs b/adapters/bevy/shared/src/components.rs index e1e9c3ab3..cbff8482e 100644 --- a/adapters/bevy/shared/src/components.rs +++ b/adapters/bevy/shared/src/components.rs @@ -1,17 +1,17 @@ use std::any::{Any, TypeId}; use std::collections::HashMap; -use bevy_ecs::{entity::Entity, component::Component, system::Resource}; +use bevy_ecs::{component::Component, entity::Entity, system::Resource}; #[derive(Component, Clone, Copy)] pub struct HostOwned { - type_id: TypeId + type_id: TypeId, } impl HostOwned { pub fn new() -> Self { Self { - type_id: TypeId::of::() + type_id: TypeId::of::(), } } @@ -41,4 +41,4 @@ impl HostOwnedMap { pub fn remove(&mut self, entity: &Entity) -> Option { self.map.remove(entity) } -} \ No newline at end of file +} diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index f81c0c85f..274de91b8 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -24,11 +24,11 @@ mod world_data; mod world_proxy; pub use change_detection::HostSyncEvent; -pub use component_access::{ComponentAccess, ComponentAccessor, AppTag}; +pub use component_access::{AppTag, ComponentAccess, ComponentAccessor}; pub use components::{HostOwned, HostOwnedMap}; pub use plugin::SharedPlugin; pub use protocol::Protocol; pub use protocol_plugin::ProtocolPlugin; -pub use system_set::{BeforeReceiveEvents, ReceiveEvents, HostSyncChangeTracking}; +pub use system_set::{BeforeReceiveEvents, HostSyncChangeTracking, ReceiveEvents}; pub use world_data::WorldData; pub use world_proxy::{WorldMut, WorldProxy, WorldProxyMut, WorldRef}; diff --git a/adapters/bevy/shared/src/plugin.rs b/adapters/bevy/shared/src/plugin.rs index de549c9cf..bef982805 100644 --- a/adapters/bevy/shared/src/plugin.rs +++ b/adapters/bevy/shared/src/plugin.rs @@ -5,13 +5,12 @@ use bevy_ecs::schedule::{IntoSystemConfigs, IntoSystemSetConfigs}; use log::warn; +use crate::change_detection::on_host_owned_added; use crate::{ change_detection::{on_despawn, HostSyncEvent}, - system_set::{HostSyncChangeTracking, BeforeHostSyncChangeTracking}, - BeforeReceiveEvents, ReceiveEvents, - HostOwnedMap, + system_set::{BeforeHostSyncChangeTracking, HostSyncChangeTracking}, + BeforeReceiveEvents, HostOwnedMap, ReceiveEvents, }; -use crate::change_detection::on_host_owned_added; pub struct SharedPlugin { phantom_t: PhantomData, @@ -34,11 +33,17 @@ impl PluginType for SharedPlugin { // EVENTS // .add_event::() // SYSTEM SETS // - .configure_sets(Update, BeforeHostSyncChangeTracking.before(HostSyncChangeTracking)) + .configure_sets( + Update, + BeforeHostSyncChangeTracking.before(HostSyncChangeTracking), + ) .configure_sets(Update, HostSyncChangeTracking.before(BeforeReceiveEvents)) .configure_sets(Update, BeforeReceiveEvents.before(ReceiveEvents)) // SYSTEMS // - .add_systems(Update, on_host_owned_added.in_set(BeforeHostSyncChangeTracking)) + .add_systems( + Update, + on_host_owned_added.in_set(BeforeHostSyncChangeTracking), + ) .add_systems(Update, on_despawn.in_set(HostSyncChangeTracking)); } } diff --git a/adapters/bevy/shared/src/world_data.rs b/adapters/bevy/shared/src/world_data.rs index f97ac6838..652173106 100644 --- a/adapters/bevy/shared/src/world_data.rs +++ b/adapters/bevy/shared/src/world_data.rs @@ -13,7 +13,7 @@ use bevy_ecs::{ use naia_shared::{ComponentKind, Replicate}; -use super::component_access::{ComponentAccess, ComponentAccessor, AppTag}; +use super::component_access::{ComponentAccess, ComponentAccessor}; #[derive(Resource)] pub struct WorldData { diff --git a/adapters/hecs/shared/src/lib.rs b/adapters/hecs/shared/src/lib.rs index 44c140769..ff46996d9 100644 --- a/adapters/hecs/shared/src/lib.rs +++ b/adapters/hecs/shared/src/lib.rs @@ -1,12 +1,12 @@ pub use naia_shared::{ BitReader, BitWrite, BitWriter, Channel, ChannelDirection, ChannelMode, ComponentFieldUpdate, - ComponentKind, ComponentKinds, ComponentUpdate, ConstBitLength, DiffMask, EntityProperty, - GlobalEntity, HostEntity, LinkConditionerConfig, LocalEntityAndGlobalEntityConverter, - LocalEntityAndGlobalEntityConverterMut, MessageBuilder, MessageContainer, - MessageHecs as Message, MessageKind, MessageKinds, Named, OwnedBitReader, OwnedLocalEntity, - Property, PropertyMutate, PropertyMutator, Random, ReliableSettings, RemoteEntity, - ReplicaDynMut, ReplicaDynRef, ReplicateBuilder, ReplicateHecs as Replicate, SerdeErr, - SerdeHecs as Serde, TickBufferSettings, UnsignedInteger, EntityAuthAccessor + ComponentKind, ComponentKinds, ComponentUpdate, ConstBitLength, DiffMask, EntityAuthAccessor, + EntityProperty, GlobalEntity, HostEntity, LinkConditionerConfig, + LocalEntityAndGlobalEntityConverter, LocalEntityAndGlobalEntityConverterMut, MessageBuilder, + MessageContainer, MessageHecs as Message, MessageKind, MessageKinds, Named, OwnedBitReader, + OwnedLocalEntity, Property, PropertyMutate, PropertyMutator, Random, ReliableSettings, + RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBuilder, ReplicateHecs as Replicate, + SerdeErr, SerdeHecs as Serde, TickBufferSettings, UnsignedInteger, }; mod component_access; diff --git a/adapters/hecs/shared/src/world_proxy.rs b/adapters/hecs/shared/src/world_proxy.rs index c4f9f7ed6..cdd60403e 100644 --- a/adapters/hecs/shared/src/world_proxy.rs +++ b/adapters/hecs/shared/src/world_proxy.rs @@ -1,6 +1,10 @@ use hecs::{Entity, World}; -use naia_shared::{ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType}; +use naia_shared::{ + ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, + LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, + ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType, +}; use super::{ component_ref::{ComponentMut, ComponentRef}, @@ -270,11 +274,20 @@ impl<'w, 'd> WorldMutType for WorldMut<'w, 'd> { None } - fn entity_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + fn entity_publish( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + ) { todo!() } - fn component_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + fn component_publish( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + _component_kind: &ComponentKind, + ) { todo!() } @@ -286,11 +299,20 @@ impl<'w, 'd> WorldMutType for WorldMut<'w, 'd> { todo!() } - fn entity_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + fn entity_enable_delegation( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + ) { todo!() } - fn component_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + fn component_enable_delegation( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + _component_kind: &ComponentKind, + ) { todo!() } diff --git a/adapters/hecs/shared/src/world_wrapper.rs b/adapters/hecs/shared/src/world_wrapper.rs index cdbe1ed03..d1f3201a2 100644 --- a/adapters/hecs/shared/src/world_wrapper.rs +++ b/adapters/hecs/shared/src/world_wrapper.rs @@ -5,7 +5,11 @@ use std::{ use hecs::{Entity, World}; -use naia_shared::{ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType}; +use naia_shared::{ + ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, + LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, + ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType, +}; use crate::{ component_ref::{ComponentMut, ComponentRef}, @@ -255,11 +259,20 @@ impl WorldMutType for &mut WorldWrapper { None } - fn entity_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + fn entity_publish( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + ) { todo!() } - fn component_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + fn component_publish( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + _component_kind: &ComponentKind, + ) { todo!() } @@ -271,11 +284,20 @@ impl WorldMutType for &mut WorldWrapper { todo!() } - fn entity_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + fn entity_enable_delegation( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + ) { todo!() } - fn component_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + fn component_enable_delegation( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + _component_kind: &ComponentKind, + ) { todo!() } diff --git a/client/src/client.rs b/client/src/client.rs index e41d009d3..9232978ff 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1323,4 +1323,4 @@ impl ConnectionStatus { pub fn is_disconnecting(&self) -> bool { self == &ConnectionStatus::Disconnecting } -} \ No newline at end of file +} diff --git a/client/src/lib.rs b/client/src/lib.rs index bd79466d9..1102e52ed 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -16,7 +16,8 @@ extern crate cfg_if; pub mod transport; pub mod shared { pub use naia_shared::{ - default_channels, sequence_greater_than, Instant, Random, SocketConfig, Tick, Message, Protocol, + default_channels, sequence_greater_than, Instant, Message, Protocol, Random, SocketConfig, + Tick, }; } pub mod internal { diff --git a/demos/basic/client/app/src/app.rs b/demos/basic/client/app/src/app.rs index a80ccd660..d791c6f4f 100644 --- a/demos/basic/client/app/src/app.rs +++ b/demos/basic/client/app/src/app.rs @@ -6,7 +6,13 @@ cfg_if! { } } -use naia_client::{shared::{default_channels::UnorderedReliableChannel, SocketConfig}, transport::webrtc, Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, RemoveComponentEvent, SpawnEntityEvent, UpdateComponentEvent, ConnectionStatus}; +use naia_client::{ + shared::{default_channels::UnorderedReliableChannel, SocketConfig}, + transport::webrtc, + Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, ConnectionStatus, + DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, + RemoveComponentEvent, SpawnEntityEvent, UpdateComponentEvent, +}; use naia_demo_world::{Entity, World}; diff --git a/demos/demo_utils/demo_world/src/world.rs b/demos/demo_utils/demo_world/src/world.rs index 3fab85889..b51b2aa64 100644 --- a/demos/demo_utils/demo_world/src/world.rs +++ b/demos/demo_utils/demo_world/src/world.rs @@ -1,6 +1,10 @@ use std::{any::Any, collections::HashMap}; -use naia_shared::{BigMap, ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType}; +use naia_shared::{ + BigMap, ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, + LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, + ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType, +}; use super::{ component_ref::{ComponentMut, ComponentRef}, @@ -296,11 +300,20 @@ impl<'w> WorldMutType for WorldMut<'w> { None } - fn entity_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + fn entity_publish( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + ) { todo!() } - fn component_publish(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + fn component_publish( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + _component_kind: &ComponentKind, + ) { todo!() } @@ -312,11 +325,20 @@ impl<'w> WorldMutType for WorldMut<'w> { todo!() } - fn entity_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity) { + fn entity_enable_delegation( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + ) { todo!() } - fn component_enable_delegation(&mut self, _global_world_manager: &dyn GlobalWorldManagerType, _entity: &Entity, _component_kind: &ComponentKind) { + fn component_enable_delegation( + &mut self, + _global_world_manager: &dyn GlobalWorldManagerType, + _entity: &Entity, + _component_kind: &ComponentKind, + ) { todo!() } diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 3aeca57dd..bf33fec42 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -115,7 +115,7 @@ pub use world::{ }, error::EntityDoesNotExistError, global_entity::GlobalEntity, - local_entity::{HostEntity, RemoteEntity, OwnedLocalEntity}, + local_entity::{HostEntity, OwnedLocalEntity, RemoteEntity}, }, host::{ global_diff_handler::GlobalDiffHandler, diff --git a/socket/client/src/backends/miniquad/packet_sender.rs b/socket/client/src/backends/miniquad/packet_sender.rs index 15ed37259..73096caaa 100644 --- a/socket/client/src/backends/miniquad/packet_sender.rs +++ b/socket/client/src/backends/miniquad/packet_sender.rs @@ -1,6 +1,8 @@ use crate::{error::NaiaClientSocketError, packet_sender::PacketSender, ServerAddr}; -use super::shared::{naia_create_u8_array, naia_send, naia_disconnect, naia_is_connected, SERVER_ADDR}; +use super::shared::{ + naia_create_u8_array, naia_disconnect, naia_is_connected, naia_send, SERVER_ADDR, +}; /// Handles sending messages to the Server for a given Client Socket #[derive(Clone, Default)] diff --git a/socket/client/src/backends/native/packet_sender.rs b/socket/client/src/backends/native/packet_sender.rs index ecda10067..9f8283fa5 100644 --- a/socket/client/src/backends/native/packet_sender.rs +++ b/socket/client/src/backends/native/packet_sender.rs @@ -1,4 +1,4 @@ -use tokio::sync::{mpsc::{Sender, error::SendError, UnboundedSender}}; +use tokio::sync::mpsc::{error::SendError, Sender, UnboundedSender}; use webrtc_unreliable_client::{AddrCell, ServerAddr as RTCServerAddr}; use crate::{error::NaiaClientSocketError, packet_sender::PacketSender, server_addr::ServerAddr}; @@ -8,17 +8,21 @@ use crate::{error::NaiaClientSocketError, packet_sender::PacketSender, server_ad pub struct PacketSenderImpl { server_addr: AddrCell, sender_channel: UnboundedSender>, - disconnect_channel: Sender<()> + disconnect_channel: Sender<()>, } impl PacketSenderImpl { /// Create a new PacketSender, if supplied with the Server's address & a /// reference back to the parent Socket - pub fn new(server_addr: AddrCell, sender_channel: UnboundedSender>, disconnect_channel: Sender<()>) -> Self { + pub fn new( + server_addr: AddrCell, + sender_channel: UnboundedSender>, + disconnect_channel: Sender<()>, + ) -> Self { PacketSenderImpl { server_addr, sender_channel, - disconnect_channel + disconnect_channel, } } } diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 768d9747c..06d415c2c 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -32,7 +32,11 @@ impl Socket { get_runtime().spawn(async move { socket.connect(&server_session_string).await }); // Setup Packet Sender - let packet_sender_impl = PacketSenderImpl::new(io.addr_cell.clone(), io.to_server_sender, io.to_server_disconnect_sender); + let packet_sender_impl = PacketSenderImpl::new( + io.addr_cell.clone(), + io.to_server_sender, + io.to_server_disconnect_sender, + ); let packet_sender: Box = Box::new(packet_sender_impl); // Setup Packet Receiver From c5406f5f7c835c6910808ee0c5d0188beaaff445 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Wed, 17 Jan 2024 14:00:26 -0600 Subject: [PATCH 14/99] expose naia_shared::Timer through naia_bevy_client and naia_bevy_shared --- adapters/bevy/client/src/lib.rs | 2 +- adapters/bevy/shared/src/lib.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index d638be1e9..ff7206b72 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -1,5 +1,5 @@ pub use naia_bevy_shared::{ - sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, + sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, Timer }; pub use naia_client::{ shared::{default_channels, Instant, Message}, diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 274de91b8..2c8e52fc8 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -9,7 +9,7 @@ pub use naia_shared::{ PropertyMutator, Random, ReliableSettings, RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBevy as Replicate, ReplicateBuilder, SerdeBevyShared as Serde, SerdeErr, SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, - UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, + UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, Timer, }; mod change_detection; From 825caf4def26f39cc126115960b8337f3663e082 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 21 Jan 2024 16:16:14 -0600 Subject: [PATCH 15/99] cargo fmt and handle simple TODO --- adapters/bevy/client/src/lib.rs | 2 +- adapters/bevy/server/src/server.rs | 3 +-- adapters/bevy/shared/src/lib.rs | 4 ++-- adapters/bevy/shared/src/plugin.rs | 10 ++++++---- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index ff7206b72..67f23b3c6 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -1,5 +1,5 @@ pub use naia_bevy_shared::{ - sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, Timer + sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, Timer, }; pub use naia_client::{ shared::{default_channels, Instant, Message}, diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index cb466c957..42495940d 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -1,9 +1,8 @@ use std::time::Duration; -use bevy_ecs::prelude::Resource; use bevy_ecs::{ entity::Entity, - system::{ResMut, SystemParam}, + system::{ResMut, SystemParam, Resource}, }; use naia_server::{ diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 2c8e52fc8..ff342ae7d 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -8,8 +8,8 @@ pub use naia_shared::{ MessageContainer, MessageKind, MessageKinds, Named, OwnedBitReader, Property, PropertyMutate, PropertyMutator, Random, ReliableSettings, RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBevy as Replicate, ReplicateBuilder, SerdeBevyShared as Serde, SerdeErr, - SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, - UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, Timer, + SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, Timer, + UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, }; mod change_detection; diff --git a/adapters/bevy/shared/src/plugin.rs b/adapters/bevy/shared/src/plugin.rs index bef982805..a8b66a702 100644 --- a/adapters/bevy/shared/src/plugin.rs +++ b/adapters/bevy/shared/src/plugin.rs @@ -3,11 +3,10 @@ use std::marker::PhantomData; use bevy_app::{App, Plugin as PluginType, Update}; use bevy_ecs::schedule::{IntoSystemConfigs, IntoSystemSetConfigs}; -use log::warn; +use log::info; -use crate::change_detection::on_host_owned_added; use crate::{ - change_detection::{on_despawn, HostSyncEvent}, + change_detection::{on_despawn, on_host_owned_added, HostSyncEvent}, system_set::{BeforeHostSyncChangeTracking, HostSyncChangeTracking}, BeforeReceiveEvents, HostOwnedMap, ReceiveEvents, }; @@ -26,7 +25,10 @@ impl SharedPlugin { impl PluginType for SharedPlugin { fn build(&self, app: &mut App) { - warn!("FIX THIS NOW CONNOR! shouldn't run this plugin twice! inspect app.world to see if this needs to happen!"); + if app.is_plugin_added::() { + info!("attempted to add SharedPlugin twice to App"); + return; + } app // RESOURCES // .init_resource::() From ddf7b5243567f0a14b43b22f52c1adc8df0bce4a Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 4 Feb 2024 18:50:53 -0600 Subject: [PATCH 16/99] fixed many demos --- client/src/client.rs | 2 - demos/basic/client/app/src/app.rs | 4 +- demos/bevy/client/src/app.rs | 5 ++- demos/bevy/client/src/systems/events.rs | 52 ++++++++++++------------ demos/bevy/client/src/systems/init.rs | 11 ++--- demos/bevy/client/src/systems/input.rs | 6 +-- demos/bevy/client/src/systems/sync.rs | 6 +-- demos/demo_utils/demo_world/src/world.rs | 28 +++++++++---- demos/macroquad/client/src/app.rs | 43 +------------------- 9 files changed, 68 insertions(+), 89 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 9232978ff..6d965e86e 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1149,9 +1149,7 @@ impl Client { ); self.manual_disconnect = false; - self.waitlist_messages = VecDeque::new(); self.global_world_manager = GlobalWorldManager::new(); - self.incoming_events = Events::new(); self.queued_entity_auth_release_messages = Vec::new(); } diff --git a/demos/basic/client/app/src/app.rs b/demos/basic/client/app/src/app.rs index d791c6f4f..9159f0305 100644 --- a/demos/basic/client/app/src/app.rs +++ b/demos/basic/client/app/src/app.rs @@ -9,7 +9,7 @@ cfg_if! { use naia_client::{ shared::{default_channels::UnorderedReliableChannel, SocketConfig}, transport::webrtc, - Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, ConnectionStatus, + Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, RemoveComponentEvent, SpawnEntityEvent, UpdateComponentEvent, }; @@ -51,7 +51,7 @@ impl App { } pub fn update(&mut self) { - if self.client.connection_status() != ConnectionStatus::Connected { + if self.client.connection_status().is_disconnected() { return; } diff --git a/demos/bevy/client/src/app.rs b/demos/bevy/client/src/app.rs index f1f5a42a9..341e0cbfe 100644 --- a/demos/bevy/client/src/app.rs +++ b/demos/bevy/client/src/app.rs @@ -10,6 +10,9 @@ use naia_bevy_demo_shared::protocol; use crate::systems::{events, init, input, sync}; +// name for the Client +pub struct Main; + #[derive(SystemSet, Debug, Hash, PartialEq, Eq, Clone)] struct MainLoop; @@ -21,7 +24,7 @@ pub fn run() { // Bevy Plugins .add_plugins(DefaultPlugins) // Add Naia Client Plugin - .add_plugins(ClientPlugin::new(ClientConfig::default(), protocol())) + .add_plugins(ClientPlugin::
::new(ClientConfig::default(), protocol())) // Background Color .insert_resource(ClearColor(Color::BLACK)) // Startup System diff --git a/demos/bevy/client/src/systems/events.rs b/demos/bevy/client/src/systems/events.rs index e64be0c39..8350253c4 100644 --- a/demos/bevy/client/src/systems/events.rs +++ b/demos/bevy/client/src/systems/events.rs @@ -1,8 +1,9 @@ use std::default::Default; use bevy::{ + log::info, prelude::{ - info, Color as BevyColor, Commands, EventReader, Query, Res, ResMut, Sprite, SpriteBundle, + Color as BevyColor, Commands, EventReader, Query, Res, ResMut, Sprite, SpriteBundle, Transform, Vec2, }, sprite::MaterialMesh2dBundle, @@ -25,16 +26,16 @@ use naia_bevy_demo_shared::{ use crate::{ components::{Confirmed, Interp, LocalCursor, Predicted}, - resources::{Global, OwnedEntity}, + resources::{Global, OwnedEntity}, app::Main, }; const SQUARE_SIZE: f32 = 32.0; pub fn connect_events( mut commands: Commands, - mut client: Client, + mut client: Client
, mut global: ResMut, - mut event_reader: EventReader, + mut event_reader: EventReader>, ) { for _ in event_reader.read() { let Ok(server_address) = client.server_address() else { @@ -68,13 +69,13 @@ pub fn connect_events( } } -pub fn reject_events(mut event_reader: EventReader) { +pub fn reject_events(mut event_reader: EventReader>) { for _ in event_reader.read() { info!("Client rejected from connecting to Server"); } } -pub fn disconnect_events(mut event_reader: EventReader) { +pub fn disconnect_events(mut event_reader: EventReader>) { for _ in event_reader.read() { info!("Client disconnected from Server"); } @@ -82,9 +83,9 @@ pub fn disconnect_events(mut event_reader: EventReader) { pub fn message_events( mut commands: Commands, - client: Client, + client: Client
, mut global: ResMut, - mut event_reader: EventReader, + mut event_reader: EventReader>, position_query: Query<&Position>, color_query: Query<&Color>, ) { @@ -163,33 +164,33 @@ pub fn message_events( } } -pub fn spawn_entity_events(mut event_reader: EventReader) { - for SpawnEntityEvent(_entity) in event_reader.read() { +pub fn spawn_entity_events(mut event_reader: EventReader>) { + for _event in event_reader.read() { info!("spawned entity"); } } -pub fn despawn_entity_events(mut event_reader: EventReader) { - for DespawnEntityEvent(_entity) in event_reader.read() { +pub fn despawn_entity_events(mut event_reader: EventReader>) { + for _event in event_reader.read() { info!("despawned entity"); } } -pub fn publish_entity_events(mut event_reader: EventReader) { - for PublishEntityEvent(_entity) in event_reader.read() { +pub fn publish_entity_events(mut event_reader: EventReader>) { + for _event in event_reader.read() { info!("client demo: publish entity event"); } } -pub fn unpublish_entity_events(mut event_reader: EventReader) { - for UnpublishEntityEvent(_entity) in event_reader.read() { +pub fn unpublish_entity_events(mut event_reader: EventReader>) { + for _event in event_reader.read() { info!("client demo: unpublish entity event"); } } pub fn insert_component_events( mut commands: Commands, - mut event_reader: EventReader, + mut event_reader: EventReader>, global: Res, sprite_query: Query<(&Shape, &Color)>, position_query: Query<&Position>, @@ -278,7 +279,7 @@ pub fn insert_component_events( pub fn update_component_events( mut global: ResMut, - mut event_reader: EventReader, + mut event_reader: EventReader>, mut position_query: Query<&mut Position>, ) { // When we receive a new Position update for the Player's Entity, @@ -328,7 +329,7 @@ pub fn update_component_events( } } -pub fn remove_component_events(mut event_reader: EventReader) { +pub fn remove_component_events(mut event_reader: EventReader>) { for events in event_reader.read() { for (_entity, _component) in events.read::() { info!("removed Position component from entity"); @@ -340,9 +341,9 @@ pub fn remove_component_events(mut event_reader: EventReader, mut global: ResMut, - mut tick_reader: EventReader, + mut tick_reader: EventReader>, mut position_query: Query<&mut Position>, ) { let Some(predicted_entity) = global @@ -357,17 +358,18 @@ pub fn tick_events( return; }; - for ClientTickEvent(client_tick) in tick_reader.read() { - if !global.command_history.can_insert(client_tick) { + for event in tick_reader.read() { + let client_tick = event.tick; + if !global.command_history.can_insert(&client_tick) { // History is full continue; } // Record command - global.command_history.insert(*client_tick, command.clone()); + global.command_history.insert(client_tick, command.clone()); // Send command - client.send_tick_buffer_message::(client_tick, &command); + client.send_tick_buffer_message::(&client_tick, &command); if let Ok(mut position) = position_query.get_mut(predicted_entity) { // Apply command diff --git a/demos/bevy/client/src/systems/init.rs b/demos/bevy/client/src/systems/init.rs index 52109d022..aa757a98b 100644 --- a/demos/bevy/client/src/systems/init.rs +++ b/demos/bevy/client/src/systems/init.rs @@ -1,15 +1,16 @@ -use bevy::prelude::{ - info, shape, Assets, Camera2dBundle, Color, ColorMaterial, Commands, Mesh, ResMut, -}; + +use bevy::{prelude::{ + shape, Assets, Camera2dBundle, Color, ColorMaterial, Commands, Mesh, ResMut, +}, log::info}; use naia_bevy_client::{transport::webrtc, Client}; use naia_bevy_demo_shared::messages::Auth; -use crate::resources::Global; +use crate::{app::Main, resources::Global}; pub fn init( mut commands: Commands, - mut client: Client, + mut client: Client
, mut meshes: ResMut>, mut materials: ResMut>, ) { diff --git a/demos/bevy/client/src/systems/input.rs b/demos/bevy/client/src/systems/input.rs index 647f89a02..d2f7e5912 100644 --- a/demos/bevy/client/src/systems/input.rs +++ b/demos/bevy/client/src/systems/input.rs @@ -3,10 +3,10 @@ use bevy::prelude::{Commands, Input, KeyCode, Query, Res, ResMut, Vec2, Window}; use naia_bevy_client::{Client, CommandsExt, ReplicationConfig}; use naia_bevy_demo_shared::{components::Position, messages::KeyCommand}; -use crate::resources::Global; +use crate::{resources::Global, app::Main}; pub fn key_input( - client: Client, + client: Client
, mut commands: Commands, mut global: ResMut, keyboard_input: Res>, @@ -42,7 +42,7 @@ pub fn key_input( if prev_config != ReplicationConfig::Private { commands .entity(entity) - .configure_replication(ReplicationConfig::Private); + .configure_replication::
(ReplicationConfig::Private); } } } diff --git a/demos/bevy/client/src/systems/sync.rs b/demos/bevy/client/src/systems/sync.rs index 2ce4999bc..f2d27729d 100644 --- a/demos/bevy/client/src/systems/sync.rs +++ b/demos/bevy/client/src/systems/sync.rs @@ -3,10 +3,10 @@ use bevy::prelude::{Query, Transform, With}; use naia_bevy_client::Client; use naia_bevy_demo_shared::components::Position; -use crate::components::{Confirmed, Interp, LocalCursor, Predicted}; +use crate::{app::Main, components::{Confirmed, Interp, LocalCursor, Predicted}}; pub fn sync_clientside_sprites( - client: Client, + client: Client
, mut query: Query<(&Position, &mut Interp, &mut Transform), With>, ) { for (position, mut interp, mut transform) in query.iter_mut() { @@ -22,7 +22,7 @@ pub fn sync_clientside_sprites( } pub fn sync_serverside_sprites( - client: Client, + client: Client
, mut query: Query<(&Position, &mut Interp, &mut Transform), With>, ) { for (position, mut interp, mut transform) in query.iter_mut() { diff --git a/demos/demo_utils/demo_world/src/world.rs b/demos/demo_utils/demo_world/src/world.rs index b51b2aa64..d52d63288 100644 --- a/demos/demo_utils/demo_world/src/world.rs +++ b/demos/demo_utils/demo_world/src/world.rs @@ -302,19 +302,33 @@ impl<'w> WorldMutType for WorldMut<'w> { fn entity_publish( &mut self, - _global_world_manager: &dyn GlobalWorldManagerType, - _entity: &Entity, + global_world_manager: &dyn GlobalWorldManagerType, + entity: &Entity, ) { - todo!() + for component_kind in WorldMutType::::component_kinds(self, entity) { + WorldMutType::::component_publish( + self, + global_world_manager, + entity, + &component_kind, + ); + } } fn component_publish( &mut self, - _global_world_manager: &dyn GlobalWorldManagerType, - _entity: &Entity, - _component_kind: &ComponentKind, + global_world_manager: &dyn GlobalWorldManagerType, + entity: &Entity, + component_kind: &ComponentKind, ) { - todo!() + if let Some(component_map) = self.world.entities.get_mut(entity) { + if let Some(component) = component_map.get_mut(component_kind) { + let diff_mask_size = component.diff_mask_size(); + let mutator = + global_world_manager.register_component(entity, &component_kind, diff_mask_size); + component.publish(&mutator); + } + } } fn entity_unpublish(&mut self, _entity: &Entity) { diff --git a/demos/macroquad/client/src/app.rs b/demos/macroquad/client/src/app.rs index c61d06a01..7736790b2 100644 --- a/demos/macroquad/client/src/app.rs +++ b/demos/macroquad/client/src/app.rs @@ -10,7 +10,7 @@ use naia_client::{ transport::webrtc, Client as NaiaClient, ClientConfig, ClientTickEvent, CommandHistory, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, InsertComponentEvent, MessageEvent, - ReplicationConfig, SpawnEntityEvent, UpdateComponentEvent, + SpawnEntityEvent, UpdateComponentEvent, }; use naia_demo_world::{Entity, World, WorldMutType, WorldRefType}; @@ -48,7 +48,6 @@ pub struct App { client: Client, world: World, owned_entity: Option, - cursor_entity: Option, interp_entities: HashMap, server_entities: HashSet, queued_command: Option, @@ -69,7 +68,6 @@ impl App { client, world: World::default(), owned_entity: None, - cursor_entity: None, interp_entities: HashMap::new(), server_entities: HashSet::new(), queued_command: None, @@ -114,22 +112,10 @@ impl App { } } } - - // Cursor events - if let Some(cursor_entity) = &self.cursor_entity { - if let Some(mut cursor_position) = self - .world - .proxy_mut() - .component_mut::(cursor_entity) - { - *cursor_position.x = macroquad::input::mouse_position().0 as i16; - *cursor_position.y = macroquad::input::mouse_position().1 as i16; - } - } } fn receive_events(&mut self) { - if !self.client.connection_status().is_connected() { + if self.client.connection_status().is_disconnected() { return; } @@ -138,19 +124,6 @@ impl App { // Connect Events for server_address in events.read::() { info!("Client connected to: {}", server_address); - - // Spawn new Client-authoritative Cursor entity - let entity = self - .client - .spawn_entity(self.world.proxy_mut()) - // This entity will be replicated to all other Clients - .configure_replication(ReplicationConfig::Public) - // Add Position component to Entity - .insert_component(Position::new(0, 0)) - // Get Entity ID - .id(); - - self.cursor_entity = Some(entity); } // Disconnect Events @@ -382,17 +355,5 @@ impl App { ); } } - - // draw own client-authoritative cursor - if let Some(entity) = &self.cursor_entity { - if let Some(position) = self.world.proxy().component::(entity) { - draw_circle( - f32::from(*position.x), - f32::from(*position.y), - CIRCLE_RADIUS, - WHITE, - ); - } - } } } From ddfc26443f54f29b300a7342386acdd1717c57a7 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 4 Feb 2024 20:18:04 -0600 Subject: [PATCH 17/99] stubbing out basic flows for request/respond --- client/src/client.rs | 108 ++++++++++++++-- demos/basic/shared/src/lib.rs | 3 +- .../shared/src/protocol/basic_request.rs | 29 +++++ .../src/{protocol.rs => protocol/mod.rs} | 4 + server/src/server.rs | 117 ++++++++++++++++-- shared/src/lib.rs | 1 + shared/src/messages/channels/channel.rs | 4 + shared/src/messages/mod.rs | 2 + shared/src/messages/request.rs | 51 ++++++++ shared/src/protocol.rs | 33 ++--- 10 files changed, 320 insertions(+), 32 deletions(-) create mode 100644 demos/basic/shared/src/protocol/basic_request.rs rename demos/basic/shared/src/{protocol.rs => protocol/mod.rs} (83%) create mode 100644 shared/src/messages/request.rs diff --git a/client/src/client.rs b/client/src/client.rs index 6d965e86e..158842dbf 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1,15 +1,9 @@ use std::{collections::VecDeque, hash::Hash, net::SocketAddr}; +use std::any::Any; use log::{info, warn}; -use naia_shared::{ - BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, - EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, - EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, - GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, - Replicate, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, - WorldMutType, WorldRefType, -}; +use naia_shared::{BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; use super::{client_config::ClientConfig, error::NaiaClientError, events::Events}; use crate::{ @@ -303,6 +297,104 @@ impl Client { } } + // + pub fn send_request(&mut self, request: &Q) -> Option> { + + let cloned_request = Q::clone_box(request); + // let response_type_id = TypeId::of::(); + let Some(id) = self.send_request_inner(&ChannelKind::of::(), cloned_request) else { + return None; + }; + Some(ResponseReceiveKey::new(id)) + } + + fn send_request_inner( + &mut self, + channel_kind: &ChannelKind, + // response_type_id: TypeId, + request_box: Box, + ) -> Option { + + let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); + + if !channel_settings.can_request_and_respond() { + std::panic!("Requests can only be sent over Bidirectional, Reliable Channels"); + } + + let request_id = self.global_request_manager.create_request_id(channel_kind); + + let Some(connection) = &mut self.server_connection else { + warn!("currently not connected to server"); + return None; + }; + let mut converter = EntityConverterMut::new( + &self.global_world_manager, + &mut connection.base.local_world_manager, + ); + + let message = MessageContainer::from_write(request_box, &mut converter); + connection.base.message_manager.send_request( + &self.protocol.message_kinds, + &mut converter, + channel_kind, + request_id, + message, + ); + + return Some(request_id); + } + + /// Sends a Response for a given Request. Returns whether or not was successful. + pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { + + let request_id = response_key.request_id(); + let Some(channel_kind) = self.global_request_manager.destroy_request_id(&request_id) else { + return false; + }; + + let cloned_response = S::clone_box(response); + + self.send_response_inner(channel_kind, request_id, cloned_response) + } + + // returns whether was successful + fn send_response_inner( + &mut self, + channel_kind: &ChannelKind, + request_id: u64, + response_box: Box, + ) -> bool { + let Some(connection) = &mut self.server_connection else { + return false; + }; + let mut converter = EntityConverterMut::new( + &self.global_world_manager, + &mut connection.base.local_world_manager, + ); + let message = MessageContainer::from_write(response_box, &mut converter); + connection.base.message_manager.send_response( + &self.protocol.message_kinds, + &mut converter, + channel_kind, + request_id, + message, + ); + return true; + } + + pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { + let response_id = response_key.response_id(); + let Some(container) = self.global_response_manager.destroy_response_id(&response_id) else { + return None; + }; + let response: S = Box::::downcast::(container.to_boxed_any()) + .ok() + .map(|boxed_m| *boxed_m) + .unwrap(); + return Some(response); + } + // + fn on_connect(&mut self) { // send queued messages let messages = std::mem::take(&mut self.waitlist_messages); diff --git a/demos/basic/shared/src/lib.rs b/demos/basic/shared/src/lib.rs index d7ed8ee09..303b02fe8 100644 --- a/demos/basic/shared/src/lib.rs +++ b/demos/basic/shared/src/lib.rs @@ -1,2 +1,3 @@ mod protocol; -pub use protocol::{protocol, Auth, Character, StringMessage}; + +pub use protocol::{protocol, Auth, Character, StringMessage, BasicRequest, BasicResponse}; diff --git a/demos/basic/shared/src/protocol/basic_request.rs b/demos/basic/shared/src/protocol/basic_request.rs new file mode 100644 index 000000000..a824e8b7a --- /dev/null +++ b/demos/basic/shared/src/protocol/basic_request.rs @@ -0,0 +1,29 @@ +use naia_shared::{Message, Request, Response}; + +#[derive(Message)] +pub struct BasicRequest { + pub contents: String, +} + +impl Request for BasicRequest { + type Response = BasicResponse; +} + +impl BasicRequest { + pub fn new(contents: String) -> Self { + Self { contents } + } +} + +#[derive(Message)] +pub struct BasicResponse { + pub contents: String, +} + +impl Response for BasicResponse {} + +impl BasicResponse { + pub fn new(contents: String) -> Self { + Self { contents } + } +} \ No newline at end of file diff --git a/demos/basic/shared/src/protocol.rs b/demos/basic/shared/src/protocol/mod.rs similarity index 83% rename from demos/basic/shared/src/protocol.rs rename to demos/basic/shared/src/protocol/mod.rs index 1762e3b9f..9b2585d7c 100644 --- a/demos/basic/shared/src/protocol.rs +++ b/demos/basic/shared/src/protocol/mod.rs @@ -5,10 +5,12 @@ use naia_shared::{LinkConditionerConfig, Protocol}; mod auth; mod character; mod string_message; +mod basic_request; pub use auth::Auth; pub use character::Character; pub use string_message::StringMessage; +pub use basic_request::{BasicRequest, BasicResponse}; // Protocol Build pub fn protocol() -> Protocol { @@ -21,6 +23,8 @@ pub fn protocol() -> Protocol { // Messages .add_message::() .add_message::() + // Requests + .add_request::() // Components .add_component::() // Build Protocol diff --git a/server/src/server.rs b/server/src/server.rs index bdb2f0721..5369ebab2 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -5,17 +5,11 @@ use std::{ panic, time::Duration, }; +use std::any::{Any}; use log::{info, warn}; -use naia_shared::{ - BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, - EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, - EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, - GlobalEntity, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, - RemoteEntity, Replicate, Serde, SerdeErr, SharedGlobalWorldManager, SocketConfig, - StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType, -}; +use naia_shared::{BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, GlobalEntity, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SerdeErr, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType}; use crate::{ connection::{ @@ -286,6 +280,113 @@ impl Server { }) } + // + pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Option> { + + let cloned_request = Q::clone_box(request); + // let response_type_id = TypeId::of::(); + let Some(id) = self.send_request_inner(user_key, &ChannelKind::of::(), cloned_request) else { + return None; + }; + Some(ResponseReceiveKey::new(id)) + } + + fn send_request_inner( + &mut self, + user_key: &UserKey, + channel_kind: &ChannelKind, + // response_type_id: TypeId, + request_box: Box, + ) -> Option { + + let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); + + if !channel_settings.can_request_and_respond() { + panic!("Requests can only be sent over Bidirectional, Reliable Channels"); + } + + let request_id = self.global_request_manager.create_request_id(user_key, channel_kind); + + let Some(user) = self.users.get(user_key) else { + warn!("user does not exist"); + return None; + }; + let Some(connection) = self.user_connections.get_mut(&user.address) else { + warn!("currently not connected to user"); + return None; + }; + let mut converter = EntityConverterMut::new( + &self.global_world_manager, + &mut connection.base.local_world_manager, + ); + + let message = MessageContainer::from_write(request_box, &mut converter); + connection.base.message_manager.send_request( + &self.protocol.message_kinds, + &mut converter, + channel_kind, + request_id, + message, + ); + + return Some(request_id); + } + + /// Sends a Response for a given Request. Returns whether or not was successful. + pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { + + let request_id = response_key.request_id(); + let Some((user_key, channel_kind)) = self.global_request_manager.destroy_request_id(&request_id) else { + return false; + }; + + let cloned_response = S::clone_box(response); + + self.send_response_inner(user_key, channel_kind, request_id, cloned_response) + } + + // returns whether was successful + fn send_response_inner( + &mut self, + user_key: &UserKey, + channel_kind: &ChannelKind, + request_id: u64, + response_box: Box, + ) -> bool { + let Some(user) = self.users.get(user_key) else { + return false; + }; + let Some(connection) = self.user_connections.get_mut(&user.address) else { + return false; + }; + let mut converter = EntityConverterMut::new( + &self.global_world_manager, + &mut connection.base.local_world_manager, + ); + let message = MessageContainer::from_write(response_box, &mut converter); + connection.base.message_manager.send_response( + &self.protocol.message_kinds, + &mut converter, + channel_kind, + request_id, + message, + ); + return true; + } + + pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { + let response_id = response_key.response_id(); + let Some(container) = self.global_response_manager.destroy_response_id(&response_id) else { + return None; + }; + let response: S = Box::::downcast::(container.to_boxed_any()) + .ok() + .map(|boxed_m| *boxed_m) + .unwrap(); + return Some(response); + } + // + pub fn receive_tick_buffer_messages(&mut self, tick: &Tick) -> TickBufferMessages { let mut tick_buffer_messages = TickBufferMessages::new(); for (_user_address, connection) in self.user_connections.iter_mut() { diff --git a/shared/src/lib.rs b/shared/src/lib.rs index bf33fec42..fc196b433 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -80,6 +80,7 @@ pub use messages::{ message_kinds::{MessageKind, MessageKinds}, message_manager::MessageManager, named::Named, + request::{Request, Response, ResponseReceiveKey, ResponseSendKey}, }; pub use world::{ component::{ diff --git a/shared/src/messages/channels/channel.rs b/shared/src/messages/channels/channel.rs index 4f2ea03b7..14f5b5d29 100644 --- a/shared/src/messages/channels/channel.rs +++ b/shared/src/messages/channels/channel.rs @@ -47,6 +47,10 @@ impl ChannelSettings { ChannelDirection::Bidirectional => true, } } + + pub fn can_request_and_respond(&self) -> bool { + self.reliable() && self.can_send_to_server() && self.can_send_to_client() + } } #[derive(Clone)] diff --git a/shared/src/messages/mod.rs b/shared/src/messages/mod.rs index ba8f4c1c0..2582bd3f8 100644 --- a/shared/src/messages/mod.rs +++ b/shared/src/messages/mod.rs @@ -5,6 +5,8 @@ pub mod message_container; pub mod message_kinds; pub mod message_manager; pub mod named; +pub mod request; #[cfg(test)] mod tests; + diff --git a/shared/src/messages/request.rs b/shared/src/messages/request.rs new file mode 100644 index 000000000..f9ef3e0e8 --- /dev/null +++ b/shared/src/messages/request.rs @@ -0,0 +1,51 @@ +use std::marker::PhantomData; + +use crate::Message; + +// Request +pub trait Request: Message { + type Response: Response; +} + +// Response +pub trait Response: Message {} + +// ResponseSendKey +#[derive(Clone, Eq, PartialEq, Hash)] +pub struct ResponseSendKey { + request_id: u64, + phantom_s: PhantomData, +} + +impl ResponseSendKey { + pub fn new(id: u64) -> Self { + Self { + request_id: id, + phantom_s: PhantomData, + } + } + + pub fn request_id(&self) -> u64 { + self.request_id + } +} + +// ResponseReceiveKey +#[derive(Clone, Eq, PartialEq, Hash)] +pub struct ResponseReceiveKey { + response_id: u64, + phantom_s: PhantomData, +} + +impl ResponseReceiveKey { + pub fn new(request_id: u64) -> Self { + Self { + response_id: request_id, + phantom_s: PhantomData, + } + } + + pub fn response_id(&self) -> u64 { + self.response_id + } +} \ No newline at end of file diff --git a/shared/src/protocol.rs b/shared/src/protocol.rs index 0c8593d5f..8ace859e2 100644 --- a/shared/src/protocol.rs +++ b/shared/src/protocol.rs @@ -2,22 +2,17 @@ use std::time::Duration; use naia_socket_shared::{LinkConditionerConfig, SocketConfig}; -use crate::{ - connection::compression_config::CompressionConfig, - messages::{ - channels::{ - channel::{Channel, ChannelDirection, ChannelMode, ChannelSettings}, - channel_kinds::ChannelKinds, - default_channels::DefaultChannelsPlugin, - system_channel::SystemChannel, - }, - fragment::FragmentedMessage, - message::Message, - message_kinds::MessageKinds, +use crate::{connection::compression_config::CompressionConfig, messages::{ + channels::{ + channel::{Channel, ChannelDirection, ChannelMode, ChannelSettings}, + channel_kinds::ChannelKinds, + default_channels::DefaultChannelsPlugin, + system_channel::SystemChannel, }, - world::component::{component_kinds::ComponentKinds, replicate::Replicate}, - EntityEventMessage, ReliableSettings, -}; + fragment::FragmentedMessage, + message::Message, + message_kinds::MessageKinds, +}, world::component::{component_kinds::ComponentKinds, replicate::Replicate}, EntityEventMessage, ReliableSettings, Request}; // Protocol Plugin pub trait ProtocolPlugin { @@ -130,6 +125,14 @@ impl Protocol { self } + pub fn add_request(&mut self) -> &mut Self { + self.check_lock(); + // Requests and Responses are handled just like Messages + self.message_kinds.add_message::(); + self.message_kinds.add_message::(); + self + } + pub fn add_component(&mut self) -> &mut Self { self.check_lock(); self.component_kinds.add_component::(); From acc4fba2b3159f36ce01ca477d122c4e8818f7e3 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 4 Feb 2024 20:56:20 -0600 Subject: [PATCH 18/99] stubbing out functions for request response --- client/src/client.rs | 9 ++- client/src/lib.rs | 1 + client/src/request.rs | 39 +++++++++++++ server/src/lib.rs | 1 + server/src/request.rs | 41 ++++++++++++++ server/src/server.rs | 11 +++- shared/src/messages/message_manager.rs | 77 ++++++++++++++++---------- 7 files changed, 146 insertions(+), 33 deletions(-) create mode 100644 client/src/request.rs create mode 100644 server/src/request.rs diff --git a/client/src/client.rs b/client/src/client.rs index 158842dbf..874083e95 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -19,6 +19,7 @@ use crate::{ global_world_manager::GlobalWorldManager, }, ReplicationConfig, + request::{GlobalRequestManager, GlobalResponseManager}, }; /// Client can send/receive messages to/from a server, and has a pool of @@ -35,6 +36,9 @@ pub struct Client { waitlist_messages: VecDeque<(ChannelKind, Box)>, // World global_world_manager: GlobalWorldManager, + // Request/Response + global_request_manager: GlobalRequestManager, + global_response_manager: GlobalResponseManager, // Events incoming_events: Events, // Hacky @@ -70,6 +74,9 @@ impl Client { waitlist_messages: VecDeque::new(), // World global_world_manager: GlobalWorldManager::new(), + // Requests + global_request_manager: GlobalRequestManager::new(), + global_response_manager: GlobalResponseManager::new(), // Events incoming_events: Events::new(), // Hacky @@ -354,7 +361,7 @@ impl Client { let cloned_response = S::clone_box(response); - self.send_response_inner(channel_kind, request_id, cloned_response) + self.send_response_inner(&channel_kind, request_id, cloned_response) } // returns whether was successful diff --git a/client/src/lib.rs b/client/src/lib.rs index 1102e52ed..c41fdc4cc 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -31,6 +31,7 @@ mod connection; mod error; mod events; mod world; +mod request; pub use client::{Client, ConnectionStatus}; pub use client_config::ClientConfig; diff --git a/client/src/request.rs b/client/src/request.rs new file mode 100644 index 000000000..dcfb6e592 --- /dev/null +++ b/client/src/request.rs @@ -0,0 +1,39 @@ +use naia_shared::{ChannelKind, MessageContainer}; + +// GlobalRequestManager +pub struct GlobalRequestManager { + +} + +impl GlobalRequestManager { + pub fn new() -> Self { + Self { + + } + } + + pub(crate) fn create_request_id(&mut self, channel_kind: &ChannelKind) -> u64 { + todo!() + } + + pub(crate) fn destroy_request_id(&mut self, request_id: &u64) -> Option { + todo!() + } +} + +// GlobalResponseManager +pub struct GlobalResponseManager { + +} + +impl GlobalResponseManager { + pub fn new() -> Self { + Self { + + } + } + + pub(crate) fn destroy_response_id(&self, response_id: &u64) -> Option { + todo!() + } +} \ No newline at end of file diff --git a/server/src/lib.rs b/server/src/lib.rs index af13ce8ef..597096381 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -38,6 +38,7 @@ mod time_manager; mod user; mod user_scope; mod world; +mod request; pub use connection::tick_buffer_messages::TickBufferMessages; pub use error::NaiaServerError; diff --git a/server/src/request.rs b/server/src/request.rs new file mode 100644 index 000000000..f0e76b931 --- /dev/null +++ b/server/src/request.rs @@ -0,0 +1,41 @@ +use naia_shared::{ChannelKind, MessageContainer}; + +use crate::UserKey; + +// GlobalRequestManager +pub struct GlobalRequestManager { + +} + +impl GlobalRequestManager { + pub fn new() -> Self { + Self { + + } + } + + pub(crate) fn create_request_id(&self, user_key: &UserKey, channel_kind: &ChannelKind) -> u64 { + todo!() + } + + pub(crate) fn destroy_request_id(&self, request_id: &u64) -> Option<(UserKey, ChannelKind)> { + todo!() + } +} + +// GlobalResponseManager +pub struct GlobalResponseManager { + +} + +impl GlobalResponseManager { + pub fn new() -> Self { + Self { + + } + } + + pub(crate) fn destroy_response_id(&self, response_id: &u64) -> Option { + todo!() + } +} \ No newline at end of file diff --git a/server/src/server.rs b/server/src/server.rs index 5369ebab2..067efb54e 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -4,8 +4,8 @@ use std::{ net::SocketAddr, panic, time::Duration, + any::Any, }; -use std::any::{Any}; use log::{info, warn}; @@ -27,6 +27,7 @@ use crate::{ }, ReplicationConfig, }; +use crate::request::{GlobalRequestManager, GlobalResponseManager}; use super::{ error::NaiaServerError, @@ -61,6 +62,9 @@ pub struct Server { global_world_manager: GlobalWorldManager, // Events incoming_events: Events, + // Requests/Responses + global_request_manager: GlobalRequestManager, + global_response_manager: GlobalResponseManager, // Ticks time_manager: TimeManager, } @@ -100,6 +104,9 @@ impl Server { global_world_manager: GlobalWorldManager::new(), // Events incoming_events: Events::new(), + // Requests/Responses + global_request_manager: GlobalRequestManager::new(), + global_response_manager: GlobalResponseManager::new(), // Ticks time_manager, } @@ -342,7 +349,7 @@ impl Server { let cloned_response = S::clone_box(response); - self.send_response_inner(user_key, channel_kind, request_id, cloned_response) + self.send_response_inner(&user_key, &channel_kind, request_id, cloned_response) } // returns whether was successful diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index 72ca99ffe..d93b62e26 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -4,38 +4,31 @@ use std::hash::Hash; use naia_serde::{BitReader, BitWrite, BitWriter, ConstBitLength, Serde, SerdeErr}; use naia_socket_shared::Instant; -use crate::{ - constants::FRAGMENTATION_LIMIT_BITS, - messages::{ - channels::{ - channel::ChannelMode, - channel::ChannelSettings, - channel_kinds::{ChannelKind, ChannelKinds}, - receivers::{ - channel_receiver::MessageChannelReceiver, - ordered_reliable_receiver::OrderedReliableReceiver, - sequenced_reliable_receiver::SequencedReliableReceiver, - sequenced_unreliable_receiver::SequencedUnreliableReceiver, - unordered_reliable_receiver::UnorderedReliableReceiver, - unordered_unreliable_receiver::UnorderedUnreliableReceiver, - }, - senders::{ - channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, - reliable_sender::ReliableSender, - sequenced_unreliable_sender::SequencedUnreliableSender, - unordered_unreliable_sender::UnorderedUnreliableSender, - }, +use crate::{constants::FRAGMENTATION_LIMIT_BITS, messages::{ + channels::{ + channel::ChannelMode, + channel::ChannelSettings, + channel_kinds::{ChannelKind, ChannelKinds}, + receivers::{ + channel_receiver::MessageChannelReceiver, + ordered_reliable_receiver::OrderedReliableReceiver, + sequenced_reliable_receiver::SequencedReliableReceiver, + sequenced_unreliable_receiver::SequencedUnreliableReceiver, + unordered_reliable_receiver::UnorderedReliableReceiver, + unordered_unreliable_receiver::UnorderedUnreliableReceiver, + }, + senders::{ + channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, + reliable_sender::ReliableSender, + sequenced_unreliable_sender::SequencedUnreliableSender, + unordered_unreliable_sender::UnorderedUnreliableSender, }, - message_container::MessageContainer, - }, - types::{HostType, MessageIndex, PacketIndex}, - world::{ - entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, - remote::entity_waitlist::EntityWaitlist, }, - EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, - Protocol, -}; + message_container::MessageContainer, +}, types::{HostType, MessageIndex, PacketIndex}, world::{ + entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, + remote::entity_waitlist::EntityWaitlist, +}, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, Protocol}; /// Handles incoming/outgoing messages, tracks the delivery status of Messages /// so that guaranteed Messages can be re-transmitted to the remote host @@ -47,6 +40,30 @@ pub struct MessageManager { message_fragmenter: MessageFragmenter, } +impl MessageManager { + pub fn send_request( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + channel_kind: &ChannelKind, + request_id: u64, + request: MessageContainer + ) { + todo!() + } + + pub fn send_response( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + channel_kind: &ChannelKind, + request_id: u64, + response: MessageContainer + ) { + todo!() + } +} + impl MessageManager { /// Creates a new MessageManager pub fn new(host_type: HostType, channel_kinds: &ChannelKinds) -> Self { From d32c6fb548ddff814d4c28387f1207f054d96bce Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 5 Feb 2024 13:58:18 -0600 Subject: [PATCH 19/99] stub out requestevents --- client/src/events.rs | 70 +++++++++++++++++-- client/src/lib.rs | 2 +- demos/basic/client/app/src/app.rs | 57 ++++++++------- demos/basic/server/src/app.rs | 31 ++++---- server/src/connection/tick_buffer_messages.rs | 2 +- server/src/events.rs | 55 +++++++++++++-- server/src/lib.rs | 2 +- 7 files changed, 165 insertions(+), 54 deletions(-) diff --git a/client/src/events.rs b/client/src/events.rs index bd94bcc18..955a030c0 100644 --- a/client/src/events.rs +++ b/client/src/events.rs @@ -1,9 +1,6 @@ use std::{collections::HashMap, marker::PhantomData, mem, net::SocketAddr, vec::IntoIter}; -use naia_shared::{ - Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, Message, - MessageContainer, MessageKind, Replicate, Tick, -}; +use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; use crate::NaiaClientError; @@ -15,6 +12,7 @@ pub struct Events { server_ticks: Vec, errors: Vec, messages: HashMap>>, + requests: HashMap>>, spawns: Vec, despawns: Vec, publishes: Vec, @@ -44,6 +42,7 @@ impl Events { server_ticks: Vec::new(), errors: Vec::new(), messages: HashMap::new(), + requests: HashMap::new(), spawns: Vec::new(), despawns: Vec::new(), publishes: Vec::new(), @@ -80,6 +79,16 @@ impl Events { mem::take(&mut self.messages) } + // This method is exposed for adapter crates ... prefer using Events.read::() instead. + pub fn has_requests(&self) -> bool { + !self.requests.is_empty() + } + pub fn take_requests( + &mut self, + ) -> HashMap>> { + mem::take(&mut self.requests) + } + // These methods are exposed for adapter crates ... prefer using Events.read::() instead. pub fn has_inserts(&self) -> bool { !self.inserts.is_empty() @@ -148,6 +157,21 @@ impl Events { self.empty = false; } + pub(crate) fn push_request(&mut self, channel_kind: &ChannelKind, message: MessageContainer) { + if !self.requests.contains_key(&channel_kind) { + self.requests.insert(*channel_kind, HashMap::new()); + } + let channel_map = self.requests.get_mut(&channel_kind).unwrap(); + + let message_kind: MessageKind = message.kind(); + if !channel_map.contains_key(&message_kind) { + channel_map.insert(message_kind, Vec::new()); + } + let list = channel_map.get_mut(&message_kind).unwrap(); + list.push(message); + self.empty = false; + } + pub(crate) fn push_client_tick(&mut self, tick: Tick) { self.client_ticks.push(tick); self.empty = false; @@ -267,6 +291,7 @@ impl Events { self.server_ticks.clear(); self.errors.clear(); self.messages.clear(); + self.requests.clear(); self.spawns.clear(); self.despawns.clear(); self.publishes.clear(); @@ -417,6 +442,43 @@ impl Event for MessageEvent { } } +// Request Event +pub struct RequestEvent { + phantom_c: PhantomData, + phantom_m: PhantomData, +} +impl Event for RequestEvent { + type Iter = IntoIter<(ResponseSendKey, Q)>; + + fn iter(events: &mut Events) -> Self::Iter { + let channel_kind: ChannelKind = ChannelKind::of::(); + if let Some(channel_map) = events.requests.get_mut(&channel_kind) { + let message_kind: MessageKind = MessageKind::of::(); + if let Some(boxed_list) = channel_map.remove(&message_kind) { + let mut output_list: Vec = Vec::new(); + + for boxed_message in boxed_list { + let boxed_any = boxed_message.to_boxed_any(); + let message = boxed_any.downcast::().unwrap(); + output_list.push(*message); + } + + todo!() + } + } + return IntoIterator::into_iter(Vec::new()); + } + + fn has(events: &Events) -> bool { + let channel_kind: ChannelKind = ChannelKind::of::(); + if let Some(channel_map) = events.requests.get(&channel_kind) { + let message_kind: MessageKind = MessageKind::of::(); + return channel_map.contains_key(&message_kind); + } + return false; + } +} + // Spawn Entity Event pub struct SpawnEntityEvent; impl Event for SpawnEntityEvent { diff --git a/client/src/lib.rs b/client/src/lib.rs index c41fdc4cc..194863de7 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -41,7 +41,7 @@ pub use events::{ ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, EntityAuthDeniedEvent, EntityAuthGrantedEvent, EntityAuthResetEvent, ErrorEvent, Events, InsertComponentEvent, MessageEvent, PublishEntityEvent, RejectEvent, RemoveComponentEvent, ServerTickEvent, - SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvent, + SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvent, RequestEvent, }; pub use world::{ entity_mut::EntityMut, entity_ref::EntityRef, replication_config::ReplicationConfig, diff --git a/demos/basic/client/app/src/app.rs b/demos/basic/client/app/src/app.rs index 9159f0305..bfa841855 100644 --- a/demos/basic/client/app/src/app.rs +++ b/demos/basic/client/app/src/app.rs @@ -10,13 +10,13 @@ use naia_client::{ shared::{default_channels::UnorderedReliableChannel, SocketConfig}, transport::webrtc, Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, - DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, + DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RequestEvent, RejectEvent, RemoveComponentEvent, SpawnEntityEvent, UpdateComponentEvent, }; use naia_demo_world::{Entity, World}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage}; +use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest}; type Client = NaiaClient; @@ -90,46 +90,46 @@ impl App { self.message_count += 1; } for entity in events.read::() { - if let Some(character) = self + if let Some(_character) = self .client .entity(self.world.proxy(), &entity) .component::() { - info!( - "creation of Character - x: {}, y: {}, name: {} {}", - *character.x, - *character.y, - (*character.fullname).first, - (*character.fullname).last, - ); + // info!( + // "creation of Character - x: {}, y: {}, name: {} {}", + // *character.x, + // *character.y, + // (*character.fullname).first, + // (*character.fullname).last, + // ); } } for _ in events.read::() { - info!("deletion of Character entity"); + // info!("deletion of Character entity"); } for (_, entity) in events.read::>() { - if let Some(character) = self + if let Some(_character) = self .client .entity(self.world.proxy(), &entity) .component::() { - info!( - "update of Character - x: {}, y: {}, name: {} {}", - *character.x, - *character.y, - (*character.fullname).first, - (*character.fullname).last, - ); + // info!( + // "update of Character - x: {}, y: {}, name: {} {}", + // *character.x, + // *character.y, + // (*character.fullname).first, + // (*character.fullname).last, + // ); } } - for (_, character) in events.read::>() { - info!( - "data delete of Character - x: {}, y: {}, name: {} {}", - *character.x, - *character.y, - (*character.fullname).first, - (*character.fullname).last, - ); + for (_, _character) in events.read::>() { + // info!( + // "data delete of Character - x: {}, y: {}, name: {} {}", + // *character.x, + // *character.y, + // (*character.fullname).first, + // (*character.fullname).last, + // ); } for _ in events.read::() { //info!("tick event"); @@ -138,5 +138,8 @@ impl App { info!("Client Error: {}", error); return; } + for (response_send_key, message) in events.read::>() { + + } } } diff --git a/demos/basic/server/src/app.rs b/demos/basic/server/src/app.rs index e59e4ac54..d2e11a182 100644 --- a/demos/basic/server/src/app.rs +++ b/demos/basic/server/src/app.rs @@ -2,13 +2,13 @@ use std::{thread::sleep, time::Duration}; use naia_server::{ shared::default_channels::UnorderedReliableChannel, transport::webrtc, AuthEvent, ConnectEvent, - DisconnectEvent, ErrorEvent, MessageEvent, RoomKey, Server as NaiaServer, ServerConfig, + DisconnectEvent, ErrorEvent, MessageEvent, RequestEvent, RoomKey, Server as NaiaServer, ServerConfig, TickEvent, }; use naia_demo_world::{Entity, World, WorldRefType}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage}; +use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest}; type Server = NaiaServer; @@ -120,17 +120,19 @@ impl App { // All game logic should happen here, on a tick event // Message sending - for user_key in self.server.user_keys() { - let new_message_contents = format!("Server Message ({})", self.tick_count); - info!( - "Server send to ({}) -> {}", - self.server.user(&user_key).address(), - new_message_contents - ); - - let new_message = StringMessage::new(new_message_contents); - self.server - .send_message::(&user_key, &new_message); + if self.tick_count % 10 == 0 { + for user_key in self.server.user_keys() { + let new_message_contents = format!("Server Message ({})", self.tick_count); + info!( + "Server send to ({}) -> {}", + self.server.user(&user_key).address(), + new_message_contents + ); + + let new_message = StringMessage::new(new_message_contents); + self.server + .send_message::(&user_key, &new_message); + } } // Iterate through Characters, marching them from (0,0) to (20, N) @@ -170,6 +172,9 @@ impl App { for error in events.read::() { info!("Naia Server Error: {}", error); } + for (user_key, response_key, request) in events.read::>() { + + } } } } diff --git a/server/src/connection/tick_buffer_messages.rs b/server/src/connection/tick_buffer_messages.rs index 071752a38..a453ef163 100644 --- a/server/src/connection/tick_buffer_messages.rs +++ b/server/src/connection/tick_buffer_messages.rs @@ -23,7 +23,7 @@ impl TickBufferMessages { channel_kind: &ChannelKind, message: MessageContainer, ) { - events::push_message(&mut self.messages, user_key, channel_kind, message); + events::push_message_impl(&mut self.messages, user_key, channel_kind, message); self.empty = false; } diff --git a/server/src/events.rs b/server/src/events.rs index 0ad0f3aa2..633b97b1e 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -2,13 +2,9 @@ use std::{any::Any, collections::HashMap, marker::PhantomData, mem, vec::IntoIte use log::warn; -use naia_shared::{ - Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, Message, - MessageContainer, MessageKind, Replicate, Tick, -}; +use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; use super::user::{User, UserKey}; - use crate::NaiaServerError; pub struct Events { @@ -18,6 +14,7 @@ pub struct Events { errors: Vec, auths: HashMap>, messages: HashMap>>, + requests: HashMap>>, spawns: Vec<(UserKey, E)>, despawns: Vec<(UserKey, E)>, publishes: Vec<(UserKey, E)>, @@ -40,6 +37,7 @@ impl Events { errors: Vec::new(), auths: HashMap::new(), messages: HashMap::new(), + requests: HashMap::new(), spawns: Vec::new(), despawns: Vec::new(), publishes: Vec::new(), @@ -78,6 +76,16 @@ impl Events { mem::take(&mut self.messages) } + // This method is exposed for adapter crates ... prefer using Events.read::() instead. + pub fn has_requests(&self) -> bool { + !self.requests.is_empty() + } + pub fn take_requests( + &mut self, + ) -> HashMap>> { + mem::take(&mut self.requests) + } + // This method is exposed for adapter crates ... prefer using Events.read::() instead. pub fn has_auths(&self) -> bool { !self.auths.is_empty() @@ -152,7 +160,17 @@ impl Events { channel_kind: &ChannelKind, message: MessageContainer, ) { - push_message(&mut self.messages, user_key, channel_kind, message); + push_message_impl(&mut self.messages, user_key, channel_kind, message); + self.empty = false; + } + + pub(crate) fn push_request( + &mut self, + user_key: &UserKey, + channel_kind: &ChannelKind, + message: MessageContainer, + ) { + push_message_impl(&mut self.requests, user_key, channel_kind, message); self.empty = false; } @@ -444,7 +462,7 @@ pub(crate) fn read_messages( output_list } -pub(crate) fn push_message( +pub(crate) fn push_message_impl( messages: &mut HashMap>>, user_key: &UserKey, channel_kind: &ChannelKind, @@ -462,6 +480,29 @@ pub(crate) fn push_message( list.push((*user_key, message)); } +// Request Event +pub struct RequestEvent { + phantom_c: PhantomData, + phantom_m: PhantomData, +} +impl Event for RequestEvent { + type Iter = IntoIter<(UserKey, ResponseSendKey, Q)>; + + fn iter(events: &mut Events) -> Self::Iter { + let output = read_channel_messages::(&mut events.requests); + todo!() + } + + fn has(events: &Events) -> bool { + let channel_kind: ChannelKind = ChannelKind::of::(); + if let Some(channel_map) = events.requests.get(&channel_kind) { + let message_kind: MessageKind = MessageKind::of::(); + return channel_map.contains_key(&message_kind); + } + return false; + } +} + // Spawn Entity Event pub struct SpawnEntityEvent; impl Event for SpawnEntityEvent { diff --git a/server/src/lib.rs b/server/src/lib.rs index 597096381..26d7d5f8c 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -46,7 +46,7 @@ pub use events::{ AuthEvent, ConnectEvent, DelegateEntityEvent, DespawnEntityEvent, DisconnectEvent, EntityAuthGrantEvent, EntityAuthResetEvent, ErrorEvent, Events, InsertComponentEvent, MessageEvent, PublishEntityEvent, RemoveComponentEvent, SpawnEntityEvent, TickEvent, - UnpublishEntityEvent, UpdateComponentEvent, + UnpublishEntityEvent, UpdateComponentEvent, RequestEvent, }; pub use room::{RoomKey, RoomMut, RoomRef}; pub use server::Server; From ca81a8499c4b97d230678014ca794a2109af3748 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 5 Feb 2024 14:25:29 -0600 Subject: [PATCH 20/99] stub out bevy adapters for new request/response functionality --- adapters/bevy/client/src/client.rs | 15 ++++++- adapters/bevy/client/src/events.rs | 44 +++++++++++++++++-- adapters/bevy/client/src/plugin.rs | 2 + adapters/bevy/client/src/systems.rs | 10 ++++- adapters/bevy/server/src/events.rs | 33 ++++++++++++-- adapters/bevy/server/src/plugin.rs | 3 +- adapters/bevy/server/src/server.rs | 19 ++++++-- adapters/bevy/server/src/systems.rs | 14 ++++-- adapters/bevy/shared/src/lib.rs | 2 +- adapters/bevy/shared/src/protocol.rs | 10 +++-- demos/bevy/client/src/app.rs | 1 + demos/bevy/client/src/systems/events.rs | 13 ++++++ demos/bevy/server/src/main.rs | 1 + demos/bevy/server/src/systems/events.rs | 13 ++++++ demos/bevy/shared/src/channels.rs | 7 +++ .../bevy/shared/src/messages/basic_request.rs | 29 ++++++++++++ demos/bevy/shared/src/messages/mod.rs | 5 ++- 17 files changed, 198 insertions(+), 23 deletions(-) create mode 100644 demos/bevy/shared/src/messages/basic_request.rs diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 54ab1842f..6b2d21b0d 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -7,7 +7,7 @@ use bevy_ecs::{ use naia_bevy_shared::{ Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, - GlobalEntity, Message, Tick, + GlobalEntity, Message, Tick, Request, Response, ResponseReceiveKey, ResponseSendKey, }; use naia_client::{ shared::SocketConfig, transport::Socket, Client as NaiaClient, ConnectionStatus, @@ -86,6 +86,19 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { .send_tick_buffer_message::(tick, message); } + /// Requests /// + pub fn send_request(&mut self, request: &Q) -> Option> { + self.client.client.send_request::(request) + } + + pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { + self.client.client.send_response(response_key, response) + } + + pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { + self.client.client.receive_response(response_key) + } + //// Ticks //// pub fn client_tick(&self) -> Option { diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 48eb7a2b6..9e325f70b 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -4,9 +4,7 @@ use bevy_ecs::{entity::Entity, prelude::Event}; use naia_client::{Events, NaiaClientError}; -use naia_bevy_shared::{ - Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Tick, -}; +use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; // ConnectEvent #[derive(Event)] @@ -105,6 +103,46 @@ impl MessageEvents { } } +// RequestEvents +#[derive(Event)] +pub struct RequestEvents { + inner: HashMap>>, + phantom_t: PhantomData, +} + +impl From<&mut Events> for RequestEvents { + fn from(events: &mut Events) -> Self { + Self { + inner: events.take_requests(), + phantom_t: PhantomData, + } + } +} + +impl RequestEvents { + pub fn read(&self) -> Vec<(ResponseSendKey, Q)> { + let mut output = Vec::new(); + + let channel_kind = ChannelKind::of::(); + if let Some(message_map) = self.inner.get(&channel_kind) { + let message_kind = MessageKind::of::(); + if let Some(messages) = message_map.get(&message_kind) { + for boxed_message in messages { + let boxed_any = boxed_message.clone().to_boxed_any(); + let message: Q = Box::::downcast::(boxed_any) + .ok() + .map(|boxed_m| *boxed_m) + .unwrap(); + // output.push(message); + todo!(); + } + } + } + + output + } +} + // ClientTickEvent #[derive(Event)] pub struct ClientTickEvent { diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index 99a6bd52f..f85ea89ad 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -5,6 +5,7 @@ use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs}; use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin, WorldData}; use naia_client::{Client, ClientConfig}; +use crate::events::RequestEvents; use super::{ client::ClientWrapper, @@ -73,6 +74,7 @@ impl PluginType for Plugin { .add_event::>() .add_event::>() .add_event::>() + .add_event::>() .add_event::>() .add_event::>() .add_event::>() diff --git a/adapters/bevy/client/src/systems.rs b/adapters/bevy/client/src/systems.rs index abd72ea6c..f0647016a 100644 --- a/adapters/bevy/client/src/systems.rs +++ b/adapters/bevy/client/src/systems.rs @@ -23,7 +23,7 @@ mod bevy_events { ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, EntityAuthDeniedEvent, EntityAuthGrantedEvent, EntityAuthResetEvent, ErrorEvent, InsertComponentEvents, MessageEvents, PublishEntityEvent, RejectEvent, RemoveComponentEvents, ServerTickEvent, - SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvents, + SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, }; } @@ -144,6 +144,14 @@ pub fn before_receive_events(world: &mut World) { event_writer.send(bevy_events::MessageEvents::from(&mut events)); } + // Request Event + if events.has_requests() { + let mut event_writer = world + .get_resource_mut::>>() + .unwrap(); + event_writer.send(bevy_events::RequestEvents::from(&mut events)); + } + // Spawn Entity Event if events.has::() { let mut event_writer = world diff --git a/adapters/bevy/server/src/events.rs b/adapters/bevy/server/src/events.rs index 8f44cb5f5..600c49a35 100644 --- a/adapters/bevy/server/src/events.rs +++ b/adapters/bevy/server/src/events.rs @@ -2,9 +2,7 @@ use std::{any::Any, collections::HashMap}; use bevy_ecs::{entity::Entity, prelude::Event}; -use naia_bevy_shared::{ - Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Tick, -}; +use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; use naia_server::{Events, NaiaServerError, User, UserKey}; // ConnectEvent @@ -93,6 +91,35 @@ fn convert_messages( output_list } +// RequestEvents +#[derive(Event)] +pub struct RequestEvents { + inner: HashMap>>, +} + +impl From<&mut Events> for RequestEvents { + fn from(events: &mut Events) -> Self { + Self { + inner: events.take_requests(), + } + } +} + +impl RequestEvents { + pub fn read(&self) -> Vec<(UserKey, ResponseSendKey, Q)> { + let channel_kind = ChannelKind::of::(); + if let Some(message_map) = self.inner.get(&channel_kind) { + let message_kind = MessageKind::of::(); + if let Some(messages) = message_map.get(&message_kind) { + // return convert_messages(messages); + todo!() + } + } + + Vec::new() + } +} + // SpawnEntityEvent #[derive(Event)] pub struct SpawnEntityEvent(pub UserKey, pub Entity); diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index 745553a8c..2d324c413 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -10,7 +10,7 @@ use super::{ events::{ AuthEvents, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, InsertComponentEvents, MessageEvents, PublishEntityEvent, RemoveComponentEvents, - SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, + SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, }, server::ServerWrapper, systems::before_receive_events, @@ -68,6 +68,7 @@ impl PluginType for Plugin { .add_event::() .add_event::() .add_event::() + .add_event::() .add_event::() .add_event::() .add_event::() diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index 42495940d..a27d573bb 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -10,10 +10,7 @@ use naia_server::{ Server as NaiaServer, TickBufferMessages, UserKey, UserMut, UserRef, UserScopeMut, }; -use naia_bevy_shared::{ - Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, - GlobalEntity, Message, Tick, -}; +use naia_bevy_shared::{Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick}; #[derive(Resource)] pub struct ServerWrapper(pub NaiaServer); @@ -65,6 +62,20 @@ impl<'w> Server<'w> { self.server.0.receive_tick_buffer_messages(tick) } + + /// Requests /// + pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Option> { + self.server.0.send_request::(user_key, request) + } + + pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { + self.server.0.send_response(response_key, response) + } + + pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { + self.server.0.receive_response(response_key) + } + //// Updates //// pub fn scope_checks(&self) -> Vec<(RoomKey, UserKey, Entity)> { diff --git a/adapters/bevy/server/src/systems.rs b/adapters/bevy/server/src/systems.rs index ab35bdcb4..052a654d7 100644 --- a/adapters/bevy/server/src/systems.rs +++ b/adapters/bevy/server/src/systems.rs @@ -4,14 +4,12 @@ use bevy_ecs::{ event::Events, world::{Mut, World}, }; - use log::warn; use naia_bevy_shared::{HostOwned, HostSyncEvent, WorldMutType, WorldProxy, WorldProxyMut}; use naia_server::EntityOwner; -use crate::plugin::Singleton; -use crate::{server::ServerWrapper, ClientOwned, EntityAuthStatus}; +use crate::{plugin::Singleton, server::ServerWrapper, ClientOwned, EntityAuthStatus}; mod naia_events { pub use naia_server::{ @@ -26,7 +24,7 @@ mod bevy_events { pub use crate::events::{ AuthEvents, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, InsertComponentEvents, MessageEvents, PublishEntityEvent, RemoveComponentEvents, - SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, + SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, }; } @@ -126,6 +124,14 @@ pub fn before_receive_events(world: &mut World) { event_writer.send(bevy_events::MessageEvents::from(&mut events)); } + // Request Event + if events.has_requests() { + let mut event_writer = world + .get_resource_mut::>() + .unwrap(); + event_writer.send(bevy_events::RequestEvents::from(&mut events)); + } + // Auth Event if events.has_auths() { let mut event_writer = world diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index ff342ae7d..544e9d3a6 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -9,7 +9,7 @@ pub use naia_shared::{ PropertyMutator, Random, ReliableSettings, RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBevy as Replicate, ReplicateBuilder, SerdeBevyShared as Serde, SerdeErr, SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, Timer, - UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, + UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, Request, Response, ResponseSendKey, ResponseReceiveKey }; mod change_detection; diff --git a/adapters/bevy/shared/src/protocol.rs b/adapters/bevy/shared/src/protocol.rs index 7e4d8fdcf..6dc3b1bb1 100644 --- a/adapters/bevy/shared/src/protocol.rs +++ b/adapters/bevy/shared/src/protocol.rs @@ -1,9 +1,6 @@ use std::time::Duration; -use naia_shared::{ - Channel, ChannelDirection, ChannelMode, ComponentKind, CompressionConfig, - LinkConditionerConfig, Message, Protocol as InnerProtocol, Replicate, -}; +use naia_shared::{Channel, ChannelDirection, ChannelMode, ComponentKind, CompressionConfig, LinkConditionerConfig, Message, Protocol as InnerProtocol, Replicate, Request}; use crate::{ProtocolPlugin, WorldData}; @@ -80,6 +77,11 @@ impl Protocol { self } + pub fn add_request(&mut self) -> &mut Self { + self.inner.add_request::(); + self + } + pub fn add_component(&mut self) -> &mut Self { self.inner.add_component::(); self.world_data diff --git a/demos/bevy/client/src/app.rs b/demos/bevy/client/src/app.rs index 341e0cbfe..d72d27da9 100644 --- a/demos/bevy/client/src/app.rs +++ b/demos/bevy/client/src/app.rs @@ -44,6 +44,7 @@ pub fn run() { events::update_component_events, events::remove_component_events, events::message_events, + events::request_events, ) .chain() .in_set(ReceiveEvents), diff --git a/demos/bevy/client/src/systems/events.rs b/demos/bevy/client/src/systems/events.rs index 8350253c4..3385b1c05 100644 --- a/demos/bevy/client/src/systems/events.rs +++ b/demos/bevy/client/src/systems/events.rs @@ -17,12 +17,15 @@ use naia_bevy_client::{ }, sequence_greater_than, Client, CommandsExt, Random, Replicate, Tick, }; +use naia_bevy_client::events::RequestEvents; use naia_bevy_demo_shared::{ behavior as shared_behavior, channels::{EntityAssignmentChannel, PlayerCommandChannel}, components::{Color, ColorValue, Position, Shape, ShapeValue}, messages::{EntityAssignment, KeyCommand}, }; +use naia_bevy_demo_shared::channels::RequestChannel; +use naia_bevy_demo_shared::messages::BasicRequest; use crate::{ components::{Confirmed, Interp, LocalCursor, Predicted}, @@ -164,6 +167,16 @@ pub fn message_events( } } +pub fn request_events( + mut event_reader: EventReader>, +) { + for events in event_reader.read() { + for (response_send_key, basic_request) in events.read::() { + + } + } +} + pub fn spawn_entity_events(mut event_reader: EventReader>) { for _event in event_reader.read() { info!("spawned entity"); diff --git a/demos/bevy/server/src/main.rs b/demos/bevy/server/src/main.rs index 54636fc0c..a8f77d5a3 100644 --- a/demos/bevy/server/src/main.rs +++ b/demos/bevy/server/src/main.rs @@ -47,6 +47,7 @@ fn main() { events::insert_component_events, events::update_component_events, events::remove_component_events, + events::request_events, ) .chain() .in_set(ReceiveEvents), diff --git a/demos/bevy/server/src/systems/events.rs b/demos/bevy/server/src/systems/events.rs index cf34430f8..7aed61866 100644 --- a/demos/bevy/server/src/systems/events.rs +++ b/demos/bevy/server/src/systems/events.rs @@ -19,6 +19,9 @@ use naia_bevy_demo_shared::{ components::{Color, ColorValue, Position, Shape, ShapeValue}, messages::{Auth, EntityAssignment, KeyCommand}, }; +use naia_bevy_demo_shared::channels::RequestChannel; +use naia_bevy_demo_shared::messages::BasicRequest; +use naia_bevy_server::events::RequestEvents; use crate::resources::Global; @@ -171,6 +174,16 @@ pub fn tick_events( } } +pub fn request_events( + mut event_reader: EventReader, +) { + for events in event_reader.read() { + for (user_key, response_send_key, basic_request) in events.read::() { + + } + } +} + pub fn spawn_entity_events( mut commands: Commands, mut server: Server, diff --git a/demos/bevy/shared/src/channels.rs b/demos/bevy/shared/src/channels.rs index d3e8f5b25..d7026be02 100644 --- a/demos/bevy/shared/src/channels.rs +++ b/demos/bevy/shared/src/channels.rs @@ -9,6 +9,9 @@ pub struct PlayerCommandChannel; #[derive(Channel)] pub struct EntityAssignmentChannel; +#[derive(Channel)] +pub struct RequestChannel; + // Plugin pub struct ChannelsPlugin; @@ -22,6 +25,10 @@ impl ProtocolPlugin for ChannelsPlugin { .add_channel::( ChannelDirection::ServerToClient, ChannelMode::UnorderedReliable(ReliableSettings::default()), + ) + .add_channel::( + ChannelDirection::Bidirectional, + ChannelMode::UnorderedReliable(ReliableSettings::default()), ); } } diff --git a/demos/bevy/shared/src/messages/basic_request.rs b/demos/bevy/shared/src/messages/basic_request.rs new file mode 100644 index 000000000..4b686cc48 --- /dev/null +++ b/demos/bevy/shared/src/messages/basic_request.rs @@ -0,0 +1,29 @@ +use naia_bevy_shared::{Message, Request, Response}; + +#[derive(Message)] +pub struct BasicRequest { + pub contents: String, +} + +impl Request for BasicRequest { + type Response = BasicResponse; +} + +impl BasicRequest { + pub fn new(contents: String) -> Self { + Self { contents } + } +} + +#[derive(Message)] +pub struct BasicResponse { + pub contents: String, +} + +impl Response for BasicResponse {} + +impl BasicResponse { + pub fn new(contents: String) -> Self { + Self { contents } + } +} \ No newline at end of file diff --git a/demos/bevy/shared/src/messages/mod.rs b/demos/bevy/shared/src/messages/mod.rs index 9f14328f0..09d57afac 100644 --- a/demos/bevy/shared/src/messages/mod.rs +++ b/demos/bevy/shared/src/messages/mod.rs @@ -3,10 +3,12 @@ use naia_bevy_shared::{Protocol, ProtocolPlugin}; mod auth; mod entity_assignment; mod key_command; +mod basic_request; pub use auth::Auth; pub use entity_assignment::EntityAssignment; pub use key_command::KeyCommand; +pub use basic_request::{BasicRequest, BasicResponse}; // Plugin pub struct MessagesPlugin; @@ -16,6 +18,7 @@ impl ProtocolPlugin for MessagesPlugin { protocol .add_message::() .add_message::() - .add_message::(); + .add_message::() + .add_request::(); } } From 2c34e6c769c0b2fa354b7e4b8d0d010a2aa03bdb Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 5 Feb 2024 15:15:43 -0600 Subject: [PATCH 21/99] message_fragment nits --- .../channels/receivers/fragment_receiver.rs | 18 ++------ .../receivers/reliable_message_receiver.rs | 18 ++++++-- shared/src/messages/message_manager.rs | 46 +++++++++---------- 3 files changed, 40 insertions(+), 42 deletions(-) diff --git a/shared/src/messages/channels/receivers/fragment_receiver.rs b/shared/src/messages/channels/receivers/fragment_receiver.rs index fd490c2bd..44ff6098e 100644 --- a/shared/src/messages/channels/receivers/fragment_receiver.rs +++ b/shared/src/messages/channels/receivers/fragment_receiver.rs @@ -6,18 +6,16 @@ use naia_serde::BitReader; use crate::{ messages::fragment::{FragmentId, FragmentedMessage}, - LocalEntityAndGlobalEntityConverter, MessageContainer, MessageIndex, MessageKinds, + LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKinds, }; pub struct FragmentReceiver { - current_index: MessageIndex, map: HashMap>)>, } impl FragmentReceiver { pub fn new() -> Self { Self { - current_index: 0, map: HashMap::new(), } } @@ -27,14 +25,10 @@ impl FragmentReceiver { message_kinds: &MessageKinds, converter: &dyn LocalEntityAndGlobalEntityConverter, message: MessageContainer, - ) -> Option<(MessageIndex, MessageContainer)> { - // returns a new index, 1 per full message + ) -> Option { - // Pass right through if not a fragment if !message.is_fragment() { - let output = Some((self.current_index, message)); - self.current_index = self.current_index.wrapping_add(1); - return output; + panic!("Received non-fragmented message in FragmentReceiver!"); } // Message is a fragment, need to process @@ -67,10 +61,6 @@ impl FragmentReceiver { panic!("Cannot read fragmented message!"); } let full_message = full_message_result.unwrap(); - let output = Some((self.current_index, full_message)); - self.current_index = self.current_index.wrapping_add(1); - output + Some(full_message) } } - -impl FragmentReceiver {} diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index 3d5cb57e0..0a2cb5967 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -32,6 +32,7 @@ pub struct ReliableMessageReceiver { arranger: A, fragment_receiver: FragmentReceiver, waitlist_store: WaitlistStore<(MessageIndex, MessageContainer)>, + current_index: MessageIndex, } impl ReliableMessageReceiver { @@ -42,6 +43,7 @@ impl ReliableMessageReceiver { arranger, fragment_receiver: FragmentReceiver::new(), waitlist_store: WaitlistStore::new(), + current_index: 0, } } @@ -52,14 +54,22 @@ impl ReliableMessageReceiver { converter: &dyn LocalEntityAndGlobalEntityConverter, message: MessageContainer, ) { - let Some((first_index, full_message)) = - self.fragment_receiver - .receive(message_kinds, converter, message) else { + let Some(full_message) = ({ + if message.is_fragment() { + self.fragment_receiver + .receive(message_kinds, converter, message) + } else { + Some(message) + } + }) else { return; }; + let first_index = self.current_index; + self.current_index = self.current_index.wrapping_add(1); + if let Some(entity_set) = full_message.relations_waiting() { - //warn!("Queing waiting message!"); + //warn!("Queuing waiting message!"); entity_waitlist.queue( &entity_set, &mut self.waitlist_store, diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index d93b62e26..93d904688 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -40,30 +40,6 @@ pub struct MessageManager { message_fragmenter: MessageFragmenter, } -impl MessageManager { - pub fn send_request( - &mut self, - message_kinds: &MessageKinds, - converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, - channel_kind: &ChannelKind, - request_id: u64, - request: MessageContainer - ) { - todo!() - } - - pub fn send_response( - &mut self, - message_kinds: &MessageKinds, - converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, - channel_kind: &ChannelKind, - request_id: u64, - response: MessageContainer - ) { - todo!() - } -} - impl MessageManager { /// Creates a new MessageManager pub fn new(host_type: HostType, channel_kinds: &ChannelKinds) -> Self { @@ -213,6 +189,28 @@ impl MessageManager { } } + pub fn send_request( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + channel_kind: &ChannelKind, + global_request_id: u64, + request: MessageContainer + ) { + todo!() + } + + pub fn send_response( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + channel_kind: &ChannelKind, + global_request_id: u64, + response: MessageContainer + ) { + todo!() + } + pub fn collect_outgoing_messages(&mut self, now: &Instant, rtt_millis: &f32) { for channel in self.channel_senders.values_mut() { channel.collect_messages(now, rtt_millis); From b4c0ac24dac4b5db18d6e42bb19624d5ffa4fd6e Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 5 Feb 2024 20:33:10 -0600 Subject: [PATCH 22/99] stubbing out request receiving --- adapters/bevy/client/src/events.rs | 32 ++--- adapters/bevy/server/src/events.rs | 31 +++-- client/src/client.rs | 10 +- client/src/connection/connection.rs | 18 ++- client/src/events.rs | 48 ++++--- client/src/lib.rs | 2 +- client/src/request.rs | 12 +- server/src/connection/connection.rs | 18 ++- server/src/events.rs | 44 ++++++- server/src/lib.rs | 2 +- server/src/request.rs | 12 +- server/src/server.rs | 1 + shared/derive/src/lib.rs | 17 ++- shared/derive/src/message.rs | 18 +++ shared/serde/src/bit_writer.rs | 4 + shared/src/lib.rs | 3 +- .../channels/receivers/channel_receiver.rs | 9 +- .../receivers/ordered_reliable_receiver.rs | 8 +- .../receivers/reliable_message_receiver.rs | 91 ++++++++----- .../receivers/sequenced_reliable_receiver.rs | 7 +- .../sequenced_unreliable_receiver.rs | 24 ++-- .../receivers/unordered_reliable_receiver.rs | 7 +- .../unordered_unreliable_receiver.rs | 17 +-- .../channels/senders/channel_sender.rs | 9 +- shared/src/messages/channels/senders/mod.rs | 1 + .../senders/reliable_message_sender.rs | 80 +++++++++++ .../channels/senders/reliable_sender.rs | 39 +----- .../senders/sequenced_unreliable_sender.rs | 22 ++-- .../senders/unordered_unreliable_sender.rs | 18 +-- shared/src/messages/local_request_sender.rs | 124 ++++++++++++++++++ shared/src/messages/message.rs | 1 + shared/src/messages/message_container.rs | 4 + shared/src/messages/message_manager.rs | 38 ++++-- shared/src/messages/mod.rs | 2 + shared/src/messages/request.rs | 14 +- shared/src/types.rs | 4 +- 36 files changed, 566 insertions(+), 225 deletions(-) create mode 100644 shared/src/messages/channels/senders/reliable_message_sender.rs create mode 100644 shared/src/messages/local_request_sender.rs diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 9e325f70b..8d36a00cf 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -2,7 +2,7 @@ use std::{any::Any, collections::HashMap, marker::PhantomData}; use bevy_ecs::{entity::Entity, prelude::Event}; -use naia_client::{Events, NaiaClientError}; +use naia_client::{shared::GlobalResponseId, Events, NaiaClientError}; use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; @@ -106,7 +106,7 @@ impl MessageEvents { // RequestEvents #[derive(Event)] pub struct RequestEvents { - inner: HashMap>>, + inner: HashMap>>, phantom_t: PhantomData, } @@ -124,19 +124,21 @@ impl RequestEvents { let mut output = Vec::new(); let channel_kind = ChannelKind::of::(); - if let Some(message_map) = self.inner.get(&channel_kind) { - let message_kind = MessageKind::of::(); - if let Some(messages) = message_map.get(&message_kind) { - for boxed_message in messages { - let boxed_any = boxed_message.clone().to_boxed_any(); - let message: Q = Box::::downcast::(boxed_any) - .ok() - .map(|boxed_m| *boxed_m) - .unwrap(); - // output.push(message); - todo!(); - } - } + let Some(request_map) = self.inner.get(&channel_kind) else { + return Vec::new(); + }; + let message_kind = MessageKind::of::(); + let Some(requests) = request_map.get(&message_kind) else { + return Vec::new(); + }; + for (global_response_id, boxed_message) in requests { + let boxed_any = boxed_message.clone().to_boxed_any(); + let request: Q = Box::::downcast::(boxed_any) + .ok() + .map(|boxed_m| *boxed_m) + .unwrap(); + let response_send_key = ResponseSendKey::new(*global_response_id); + output.push((response_send_key, request)); } output diff --git a/adapters/bevy/server/src/events.rs b/adapters/bevy/server/src/events.rs index 600c49a35..f9e63598a 100644 --- a/adapters/bevy/server/src/events.rs +++ b/adapters/bevy/server/src/events.rs @@ -3,7 +3,7 @@ use std::{any::Any, collections::HashMap}; use bevy_ecs::{entity::Entity, prelude::Event}; use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; -use naia_server::{Events, NaiaServerError, User, UserKey}; +use naia_server::{shared::GlobalResponseId, Events, NaiaServerError, User, UserKey}; // ConnectEvent #[derive(Event)] @@ -94,7 +94,7 @@ fn convert_messages( // RequestEvents #[derive(Event)] pub struct RequestEvents { - inner: HashMap>>, + inner: HashMap>>, } impl From<&mut Events> for RequestEvents { @@ -108,15 +108,28 @@ impl From<&mut Events> for RequestEvents { impl RequestEvents { pub fn read(&self) -> Vec<(UserKey, ResponseSendKey, Q)> { let channel_kind = ChannelKind::of::(); - if let Some(message_map) = self.inner.get(&channel_kind) { - let message_kind = MessageKind::of::(); - if let Some(messages) = message_map.get(&message_kind) { - // return convert_messages(messages); - todo!() + let Some(request_map) = self.inner.get(&channel_kind) else { + return Vec::new(); + }; + let message_kind = MessageKind::of::(); + let Some(requests) = request_map.get(&message_kind) else { + return Vec::new(); + }; + + let mut output_list: Vec<(UserKey, ResponseSendKey, Q)> = Vec::new(); + + for (user_key, global_response_id, request) in requests { + let message: Q = Box::::downcast::(request.clone().to_boxed_any()) + .ok() + .map(|boxed_m| *boxed_m) + .unwrap(); + + let response_send_key = ResponseSendKey::new(*global_response_id); + + output_list.push((*user_key, response_send_key, message)); } - } - Vec::new() + return output_list; } } diff --git a/client/src/client.rs b/client/src/client.rs index 874083e95..ac9fee953 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1,9 +1,8 @@ -use std::{collections::VecDeque, hash::Hash, net::SocketAddr}; -use std::any::Any; +use std::{any::Any, collections::VecDeque, hash::Hash, net::SocketAddr}; use log::{info, warn}; -use naia_shared::{BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; +use naia_shared::{BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, GlobalRequestId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; use super::{client_config::ClientConfig, error::NaiaClientError, events::Events}; use crate::{ @@ -205,7 +204,8 @@ impl Client { // receive packets, process into events response_events = Some(connection.process_packets( &mut self.global_world_manager, - &self.protocol.component_kinds, + &mut self.global_response_manager, + &self.protocol, &mut world, &mut self.incoming_events, )); @@ -320,7 +320,7 @@ impl Client { channel_kind: &ChannelKind, // response_type_id: TypeId, request_box: Box, - ) -> Option { + ) -> Option { let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); diff --git a/client/src/connection/connection.rs b/client/src/connection/connection.rs index 84fd4693c..ad2b311e3 100644 --- a/client/src/connection/connection.rs +++ b/client/src/connection/connection.rs @@ -3,13 +3,14 @@ use std::{any::Any, hash::Hash}; use log::warn; use naia_shared::{ - BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, ComponentKinds, + BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, EntityEventMessage, EntityEventMessageAction, EntityResponseEvent, HostType, HostWorldEvents, Instant, OwnedBitReader, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType, }; use crate::{ + request::GlobalResponseManager, connection::{ io::Io, tick_buffer_sender::TickBufferSender, tick_queue::TickQueue, time_manager::TimeManager, @@ -108,13 +109,15 @@ impl Connection { pub fn process_packets>( &mut self, global_world_manager: &mut GlobalWorldManager, - component_kinds: &ComponentKinds, + global_response_manager: &mut GlobalResponseManager, + protocol: &Protocol, world: &mut W, incoming_events: &mut Events, ) -> Vec> { let mut response_events = Vec::new(); // Receive Message Events let messages = self.base.message_manager.receive_messages( + &protocol.message_kinds, global_world_manager, &self.base.local_world_manager, &mut self.base.remote_world_manager.entity_waitlist, @@ -153,12 +156,21 @@ impl Connection { } } + // Receive Request Events + let requests = self.base.message_manager.receive_requests(); + for (channel_kind, requests) in requests { + for (message_kind, local_response_id, request) in requests { + let global_response_id = global_response_manager.create_response_id(&channel_kind, &message_kind, &local_response_id); + incoming_events.push_request(&channel_kind, global_response_id, request); + } + } + // Receive World Events let remote_events = self.base.remote_world_reader.take_incoming_events(); let world_events = self.base.remote_world_manager.process_world_events( global_world_manager, &mut self.base.local_world_manager, - component_kinds, + &protocol.component_kinds, world, remote_events, ); diff --git a/client/src/events.rs b/client/src/events.rs index 955a030c0..ae0e76a01 100644 --- a/client/src/events.rs +++ b/client/src/events.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, marker::PhantomData, mem, net::SocketAddr, vec::IntoIter}; -use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, GlobalResponseId, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; use crate::NaiaClientError; @@ -12,7 +12,7 @@ pub struct Events { server_ticks: Vec, errors: Vec, messages: HashMap>>, - requests: HashMap>>, + requests: HashMap>>, spawns: Vec, despawns: Vec, publishes: Vec, @@ -85,7 +85,7 @@ impl Events { } pub fn take_requests( &mut self, - ) -> HashMap>> { + ) -> HashMap>> { mem::take(&mut self.requests) } @@ -157,18 +157,24 @@ impl Events { self.empty = false; } - pub(crate) fn push_request(&mut self, channel_kind: &ChannelKind, message: MessageContainer) { + pub(crate) fn push_request( + &mut self, + channel_kind: &ChannelKind, + global_response_id: GlobalResponseId, + request: MessageContainer, + ) { if !self.requests.contains_key(&channel_kind) { self.requests.insert(*channel_kind, HashMap::new()); } let channel_map = self.requests.get_mut(&channel_kind).unwrap(); - let message_kind: MessageKind = message.kind(); + let message_kind: MessageKind = request.kind(); if !channel_map.contains_key(&message_kind) { channel_map.insert(message_kind, Vec::new()); } let list = channel_map.get_mut(&message_kind).unwrap(); - list.push(message); + list.push((global_response_id, request)); + self.empty = false; } @@ -452,21 +458,23 @@ impl Event for RequestEvent { fn iter(events: &mut Events) -> Self::Iter { let channel_kind: ChannelKind = ChannelKind::of::(); - if let Some(channel_map) = events.requests.get_mut(&channel_kind) { - let message_kind: MessageKind = MessageKind::of::(); - if let Some(boxed_list) = channel_map.remove(&message_kind) { - let mut output_list: Vec = Vec::new(); - - for boxed_message in boxed_list { - let boxed_any = boxed_message.to_boxed_any(); - let message = boxed_any.downcast::().unwrap(); - output_list.push(*message); - } - - todo!() - } + let Some(channel_map) = events.requests.get_mut(&channel_kind) else { + return IntoIterator::into_iter(Vec::new()); + }; + let message_kind: MessageKind = MessageKind::of::(); + let Some(requests) = channel_map.remove(&message_kind) else { + return IntoIterator::into_iter(Vec::new()); + }; + let mut output_list = Vec::new(); + + for (global_response_id, boxed_request) in requests { + let boxed_any = boxed_request.to_boxed_any(); + let request = boxed_any.downcast::().unwrap(); + let response_send_key = ResponseSendKey::::new(global_response_id); + output_list.push((response_send_key, *request)); } - return IntoIterator::into_iter(Vec::new()); + + return IntoIterator::into_iter(output_list); } fn has(events: &Events) -> bool { diff --git a/client/src/lib.rs b/client/src/lib.rs index 194863de7..83a9a8faf 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -17,7 +17,7 @@ pub mod transport; pub mod shared { pub use naia_shared::{ default_channels, sequence_greater_than, Instant, Message, Protocol, Random, SocketConfig, - Tick, + Tick, GlobalResponseId, }; } pub mod internal { diff --git a/client/src/request.rs b/client/src/request.rs index dcfb6e592..693063435 100644 --- a/client/src/request.rs +++ b/client/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, MessageContainer}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer, MessageKind}; // GlobalRequestManager pub struct GlobalRequestManager { @@ -12,11 +12,11 @@ impl GlobalRequestManager { } } - pub(crate) fn create_request_id(&mut self, channel_kind: &ChannelKind) -> u64 { + pub(crate) fn create_request_id(&mut self, channel_kind: &ChannelKind) -> GlobalRequestId { todo!() } - pub(crate) fn destroy_request_id(&mut self, request_id: &u64) -> Option { + pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option { todo!() } } @@ -33,7 +33,11 @@ impl GlobalResponseManager { } } - pub(crate) fn destroy_response_id(&self, response_id: &u64) -> Option { + pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_response_id: &LocalResponseId) -> GlobalResponseId { + todo!() + } + + pub(crate) fn destroy_response_id(&self, response_id: &GlobalResponseId) -> Option { todo!() } } \ No newline at end of file diff --git a/server/src/connection/connection.rs b/server/src/connection/connection.rs index b0f4032e3..7a2116b50 100644 --- a/server/src/connection/connection.rs +++ b/server/src/connection/connection.rs @@ -2,11 +2,7 @@ use std::{any::Any, hash::Hash, net::SocketAddr}; use log::warn; -use naia_shared::{ - BaseConnection, BigMapKey, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, - EntityEventMessage, EntityResponseEvent, HostType, HostWorldEvents, Instant, PacketType, - Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType, -}; +use naia_shared::{BaseConnection, BigMapKey, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, EntityEventMessage, EntityResponseEvent, HostType, HostWorldEvents, Instant, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; use crate::{ connection::{ @@ -18,6 +14,7 @@ use crate::{ user::UserKey, world::global_world_manager::GlobalWorldManager, }; +use crate::request::GlobalResponseManager; use super::ping_manager::PingManager; @@ -100,12 +97,14 @@ impl Connection { &mut self, protocol: &Protocol, global_world_manager: &mut GlobalWorldManager, + global_response_manager: &mut GlobalResponseManager, world: &mut W, incoming_events: &mut Events, ) -> Vec> { let mut response_events = Vec::new(); // Receive Message Events let messages = self.base.message_manager.receive_messages( + &protocol.message_kinds, global_world_manager, &self.base.local_world_manager, &mut self.base.remote_world_manager.entity_waitlist, @@ -137,6 +136,15 @@ impl Connection { } } + // Receive Request Events + let requests = self.base.message_manager.receive_requests(); + for (channel_kind, requests) in requests { + for (message_kind, local_request_id, request) in requests { + let global_response_id = global_response_manager.create_response_id(&channel_kind, &message_kind, &local_request_id); + incoming_events.push_request(&self.user_key, &channel_kind, global_response_id, request); + } + } + // Receive World Events if protocol.client_authoritative_entities { let remote_events = self.base.remote_world_reader.take_incoming_events(); diff --git a/server/src/events.rs b/server/src/events.rs index 633b97b1e..ac3ce0ed2 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -2,7 +2,7 @@ use std::{any::Any, collections::HashMap, marker::PhantomData, mem, vec::IntoIte use log::warn; -use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, GlobalResponseId, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; use super::user::{User, UserKey}; use crate::NaiaServerError; @@ -14,7 +14,7 @@ pub struct Events { errors: Vec, auths: HashMap>, messages: HashMap>>, - requests: HashMap>>, + requests: HashMap>>, spawns: Vec<(UserKey, E)>, despawns: Vec<(UserKey, E)>, publishes: Vec<(UserKey, E)>, @@ -82,7 +82,7 @@ impl Events { } pub fn take_requests( &mut self, - ) -> HashMap>> { + ) -> HashMap>> { mem::take(&mut self.requests) } @@ -168,9 +168,20 @@ impl Events { &mut self, user_key: &UserKey, channel_kind: &ChannelKind, - message: MessageContainer, + global_response_id: GlobalResponseId, + request: MessageContainer, ) { - push_message_impl(&mut self.requests, user_key, channel_kind, message); + if !self.requests.contains_key(&channel_kind) { + self.requests.insert(*channel_kind, HashMap::new()); + } + let channel_map = self.requests.get_mut(&channel_kind).unwrap(); + let request_type_id = request.kind(); + if !channel_map.contains_key(&request_type_id) { + channel_map.insert(request_type_id, Vec::new()); + } + let list = channel_map.get_mut(&request_type_id).unwrap(); + list.push((*user_key, global_response_id, request)); + self.empty = false; } @@ -489,8 +500,27 @@ impl Event for RequestEvent { type Iter = IntoIter<(UserKey, ResponseSendKey, Q)>; fn iter(events: &mut Events) -> Self::Iter { - let output = read_channel_messages::(&mut events.requests); - todo!() + let channel_kind: ChannelKind = ChannelKind::of::(); + let Some(channel_map) = events.requests.get_mut(&channel_kind) else { + return IntoIterator::into_iter(Vec::new()); + }; + let message_kind: MessageKind = MessageKind::of::(); + let Some(requests) = channel_map.remove(&message_kind) else { + return IntoIterator::into_iter(Vec::new()); + }; + + let mut output_list = Vec::new(); + + for (user_key, global_response_id, request) in requests { + let request: Q = Box::::downcast::(request.to_boxed_any()) + .ok() + .map(|boxed_q| *boxed_q) + .unwrap(); + let response_send_key = ResponseSendKey::::new(global_response_id); + output_list.push((user_key, response_send_key, request)); + } + + return IntoIterator::into_iter(output_list); } fn has(events: &Events) -> bool { diff --git a/server/src/lib.rs b/server/src/lib.rs index 26d7d5f8c..b6422095c 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -18,7 +18,7 @@ pub mod shared { pub use naia_shared::{ default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, Random, Serde, SerdeErr, SignedInteger, SignedVariableInteger, SocketConfig, - UnsignedInteger, UnsignedVariableInteger, + UnsignedInteger, UnsignedVariableInteger, GlobalResponseId, }; } pub mod internal { diff --git a/server/src/request.rs b/server/src/request.rs index f0e76b931..6b5a780cd 100644 --- a/server/src/request.rs +++ b/server/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, MessageContainer}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer, MessageKind}; use crate::UserKey; @@ -14,11 +14,11 @@ impl GlobalRequestManager { } } - pub(crate) fn create_request_id(&self, user_key: &UserKey, channel_kind: &ChannelKind) -> u64 { + pub(crate) fn create_request_id(&self, user_key: &UserKey, channel_kind: &ChannelKind) -> GlobalRequestId { todo!() } - pub(crate) fn destroy_request_id(&self, request_id: &u64) -> Option<(UserKey, ChannelKind)> { + pub(crate) fn destroy_request_id(&self, request_id: &GlobalRequestId) -> Option<(UserKey, ChannelKind)> { todo!() } } @@ -35,7 +35,11 @@ impl GlobalResponseManager { } } - pub(crate) fn destroy_response_id(&self, response_id: &u64) -> Option { + pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_request_id: &LocalResponseId) -> GlobalResponseId { + todo!() + } + + pub(crate) fn destroy_response_id(&self, response_id: &GlobalResponseId) -> Option { todo!() } } \ No newline at end of file diff --git a/server/src/server.rs b/server/src/server.rs index 067efb54e..53da82dc8 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -1804,6 +1804,7 @@ impl Server { connection.process_packets( &self.protocol, &mut self.global_world_manager, + &mut self.global_response_manager, world, &mut self.incoming_events, ), diff --git a/shared/derive/src/lib.rs b/shared/derive/src/lib.rs index cdd022bf2..8c42ee050 100644 --- a/shared/derive/src/lib.rs +++ b/shared/derive/src/lib.rs @@ -51,33 +51,40 @@ pub fn channel_derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream #[proc_macro_derive(MessageInternal)] pub fn message_derive_internal(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let shared_crate_name = quote! { crate }; - message_impl(input, shared_crate_name, false) + message_impl(input, shared_crate_name, false, false) } /// Derives the Message trait for a given struct, for FragmentedMessage #[proc_macro_derive(MessageFragment)] pub fn message_derive_fragment(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let shared_crate_name = quote! { crate }; - message_impl(input, shared_crate_name, true) + message_impl(input, shared_crate_name, true, false) +} + +/// Derives the Message trait for a given struct, for RequestMessage +#[proc_macro_derive(MessageRequest)] +pub fn message_derive_request(input: proc_macro::TokenStream) -> proc_macro::TokenStream { + let shared_crate_name = quote! { crate }; + message_impl(input, shared_crate_name, false, true) } /// Derives the Message trait for a given struct #[proc_macro_derive(Message)] pub fn message_derive_shared(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let shared_crate_name = quote! { naia_shared }; - message_impl(input, shared_crate_name, false) + message_impl(input, shared_crate_name, false, false) } /// Derives the Message trait for a given struct, for the Bevy adapter #[proc_macro_derive(MessageBevy)] pub fn message_derive_bevy(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let shared_crate_name = quote! { naia_bevy_shared }; - message_impl(input, shared_crate_name, false) + message_impl(input, shared_crate_name, false, false) } /// Derives the Message trait for a given struct, for the Hecs adapter #[proc_macro_derive(MessageHecs)] pub fn message_derive_hecs(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let shared_crate_name = quote! { naia_hecs_shared }; - message_impl(input, shared_crate_name, false) + message_impl(input, shared_crate_name, false, false) } diff --git a/shared/derive/src/message.rs b/shared/derive/src/message.rs index 036328129..2f4fdb701 100644 --- a/shared/derive/src/message.rs +++ b/shared/derive/src/message.rs @@ -8,6 +8,7 @@ pub fn message_impl( input: proc_macro::TokenStream, shared_crate_name: TokenStream, is_fragment: bool, + is_request: bool, ) -> proc_macro::TokenStream { let input = parse_macro_input!(input as DeriveInput); @@ -34,6 +35,7 @@ pub fn message_impl( let create_builder_method = get_create_builder_method(&builder_name); let read_method = get_read_method(&struct_name, &fields, &struct_type); let is_fragment_method = get_is_fragment_method(is_fragment); + let is_request_method = get_is_request_method(is_request); let gen = quote! { mod #module_name { @@ -58,6 +60,7 @@ pub fn message_impl( self } #is_fragment_method + #is_request_method #bit_length_method #create_builder_method #relations_waiting_method @@ -93,6 +96,21 @@ fn get_is_fragment_method(is_fragment: bool) -> TokenStream { } } +fn get_is_request_method(is_request: bool) -> TokenStream { + let value = { + if is_request { + quote! { true } + } else { + quote! { false } + } + }; + quote! { + fn is_request(&self) -> bool { + #value + } + } +} + fn get_clone_method(fields: &[Field], struct_type: &StructType) -> TokenStream { let mut output = quote! {}; diff --git a/shared/serde/src/bit_writer.rs b/shared/serde/src/bit_writer.rs index aafd83209..29b141f3c 100644 --- a/shared/serde/src/bit_writer.rs +++ b/shared/serde/src/bit_writer.rs @@ -46,6 +46,10 @@ impl BitWriter { } } + pub fn with_max_capacity() -> Self { + Self::with_capacity(u32::MAX) + } + fn finalize(&mut self) { if self.scratch_index > 0 { self.buffer[self.buffer_index] = diff --git a/shared/src/lib.rs b/shared/src/lib.rs index fc196b433..a8baa7039 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -81,6 +81,7 @@ pub use messages::{ message_manager::MessageManager, named::Named, request::{Request, Response, ResponseReceiveKey, ResponseSendKey}, + local_request_sender::{RequestMessage, LocalResponseId}, }; pub use world::{ component::{ @@ -137,5 +138,5 @@ pub use bigmap::{BigMap, BigMapKey}; pub use game_time::{GameDuration, GameInstant, GAME_TIME_LIMIT}; pub use key_generator::KeyGenerator; pub use protocol::{Protocol, ProtocolPlugin}; -pub use types::{HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick}; +pub use types::{HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick, GlobalRequestId, GlobalResponseId}; pub use wrapping_number::{sequence_greater_than, sequence_less_than, wrapping_diff}; diff --git a/shared/src/messages/channels/receivers/channel_receiver.rs b/shared/src/messages/channels/receivers/channel_receiver.rs index 112cbc183..38cfcd6f0 100644 --- a/shared/src/messages/channels/receivers/channel_receiver.rs +++ b/shared/src/messages/channels/receivers/channel_receiver.rs @@ -1,15 +1,12 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{ - messages::{message_container::MessageContainer, message_kinds::MessageKinds}, - world::remote::entity_waitlist::EntityWaitlist, - LocalEntityAndGlobalEntityConverter, -}; +use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds, local_request_sender::LocalRequestId}, world::remote::entity_waitlist::EntityWaitlist, LocalEntityAndGlobalEntityConverter, MessageKind}; pub trait ChannelReceiver

: Send + Sync { /// Read messages from an internal buffer and return their content fn receive_messages( &mut self, + message_kinds: &MessageKinds, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec

; @@ -24,4 +21,6 @@ pub trait MessageChannelReceiver: ChannelReceiver { converter: &dyn LocalEntityAndGlobalEntityConverter, reader: &mut BitReader, ) -> Result<(), SerdeErr>; + + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)>; } diff --git a/shared/src/messages/channels/receivers/ordered_reliable_receiver.rs b/shared/src/messages/channels/receivers/ordered_reliable_receiver.rs index f2713d8a3..800c17018 100644 --- a/shared/src/messages/channels/receivers/ordered_reliable_receiver.rs +++ b/shared/src/messages/channels/receivers/ordered_reliable_receiver.rs @@ -29,10 +29,10 @@ pub struct OrderedArranger { impl ReceiverArranger for OrderedArranger { fn process( &mut self, - incoming_messages: &mut Vec<(MessageIndex, MessageContainer)>, message_index: MessageIndex, message: MessageContainer, - ) { + ) -> Vec<(MessageIndex, MessageContainer)> { + let mut output = Vec::new(); let mut current_index = 0; // Put message where it needs to go in buffer @@ -67,13 +67,13 @@ impl ReceiverArranger for OrderedArranger { loop { let Some((_, Some(_))) = self.buffer.front() else { // no more messages, return - return; + return output; }; let Some((index, Some(message))) = self.buffer.pop_front() else { panic!("shouldn't be possible due to above check"); }; - incoming_messages.push((index, message)); + output.push((index, message)); self.oldest_received_message_index = self.oldest_received_message_index.wrapping_add(1); } } diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index 0a2cb5967..95740052c 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -1,38 +1,34 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{ - messages::{ - channels::receivers::{ - channel_receiver::{ChannelReceiver, MessageChannelReceiver}, - fragment_receiver::FragmentReceiver, - indexed_message_reader::IndexedMessageReader, - reliable_receiver::ReliableReceiver, - }, - message_kinds::MessageKinds, +use crate::{messages::{ + local_request_sender::LocalRequestId, + channels::receivers::{ + channel_receiver::{ChannelReceiver, MessageChannelReceiver}, + fragment_receiver::FragmentReceiver, + indexed_message_reader::IndexedMessageReader, + reliable_receiver::ReliableReceiver, }, - types::MessageIndex, - world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, - LocalEntityAndGlobalEntityConverter, MessageContainer, -}; + message_kinds::MessageKinds, +}, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, RequestMessage}; // Receiver Arranger Trait pub trait ReceiverArranger: Send + Sync { fn process( &mut self, - incoming_messages: &mut Vec<(MessageIndex, MessageContainer)>, message_index: MessageIndex, message: MessageContainer, - ); + ) -> Vec<(MessageIndex, MessageContainer)>; } // Reliable Receiver pub struct ReliableMessageReceiver { reliable_receiver: ReliableReceiver, - incoming_messages: Vec<(MessageIndex, MessageContainer)>, + incoming_messages: Vec, arranger: A, fragment_receiver: FragmentReceiver, waitlist_store: WaitlistStore<(MessageIndex, MessageContainer)>, current_index: MessageIndex, + incoming_requests: Vec<(MessageKind, LocalRequestId, MessageContainer)>, } impl ReliableMessageReceiver { @@ -44,6 +40,7 @@ impl ReliableMessageReceiver { fragment_receiver: FragmentReceiver::new(), waitlist_store: WaitlistStore::new(), current_index: 0, + incoming_requests: Vec::new(), } } @@ -80,8 +77,10 @@ impl ReliableMessageReceiver { //info!("Received message!"); } - self.arranger - .process(&mut self.incoming_messages, first_index, full_message); + let incoming_messages = self.arranger.process(first_index, full_message); + for (_, message) in incoming_messages { + self.receive_message(message_kinds, converter, message); + } } pub fn buffer_message( @@ -100,34 +99,56 @@ impl ReliableMessageReceiver { } } - pub fn receive_messages( + fn receive_message( &mut self, - entity_waitlist: &mut EntityWaitlist, + message_kinds: &MessageKinds, converter: &dyn LocalEntityAndGlobalEntityConverter, - ) -> Vec<(MessageIndex, MessageContainer)> { - if let Some(list) = entity_waitlist.collect_ready_items(&mut self.waitlist_store) { - for (first_index, mut full_message) in list { - full_message.relations_complete(converter); - self.arranger - .process(&mut self.incoming_messages, first_index, full_message); + message_container: MessageContainer + ) { + // look at message, see if it's a request + if message_container.is_request() { + // it is! cast it + let request_container = message_container + .to_boxed_any() + .downcast::() + .unwrap(); + let (local_request_id, request_bytes) = request_container.to_id_and_bytes(); + let mut reader = BitReader::new(&request_bytes); + let request_result = message_kinds.read(&mut reader, converter); + if request_result.is_err() { + // TODO: bubble up error instead of panicking here + panic!("Cannot read request message!"); } + let request = request_result.unwrap(); + // add it to incoming requests + self.incoming_requests + .push((request.kind(), local_request_id, request)); + } else { + // it's not a request, just add it to incoming messages + self.incoming_messages.push(message_container); } - - // return buffer - std::mem::take(&mut self.incoming_messages) } } impl ChannelReceiver for ReliableMessageReceiver { fn receive_messages( &mut self, + message_kinds: &MessageKinds, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec { - self.receive_messages(entity_waitlist, converter) - .drain(..) - .map(|(_, message)| message) - .collect() + if let Some(list) = entity_waitlist.collect_ready_items(&mut self.waitlist_store) { + for (first_index, mut full_message) in list { + full_message.relations_complete(converter); + let incoming_messages = self.arranger.process(first_index, full_message); + for (_, message) in incoming_messages { + self.receive_message(message_kinds, converter, message); + } + } + } + + // return buffer + std::mem::take(&mut self.incoming_messages) } } @@ -145,4 +166,8 @@ impl MessageChannelReceiver for ReliableMessageReceiver } Ok(()) } + + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)> { + std::mem::take(&mut self.incoming_requests) + } } diff --git a/shared/src/messages/channels/receivers/sequenced_reliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_reliable_receiver.rs index d1175c8f0..b1a67bef3 100644 --- a/shared/src/messages/channels/receivers/sequenced_reliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_reliable_receiver.rs @@ -25,13 +25,14 @@ pub struct SequencedArranger { impl ReceiverArranger for SequencedArranger { fn process( &mut self, - incoming_messages: &mut Vec<(MessageIndex, MessageContainer)>, message_index: MessageIndex, message: MessageContainer, - ) { + ) -> Vec<(MessageIndex, MessageContainer)> { + let mut output = Vec::new(); if !sequence_less_than(message_index, self.newest_received_message_index) { self.newest_received_message_index = message_index; - incoming_messages.push((message_index, message)); + output.push((message_index, message)); } + output } } diff --git a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs index 2c72026d0..b6696eb0a 100644 --- a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs @@ -2,19 +2,14 @@ use std::mem; use naia_serde::{BitReader, SerdeErr}; -use crate::{ - messages::{ - channels::receivers::{ - channel_receiver::{ChannelReceiver, MessageChannelReceiver}, - indexed_message_reader::IndexedMessageReader, - }, - message_kinds::MessageKinds, +use crate::{messages::{ + local_request_sender::LocalRequestId, + channels::receivers::{ + channel_receiver::{ChannelReceiver, MessageChannelReceiver}, + indexed_message_reader::IndexedMessageReader, }, - sequence_greater_than, - types::MessageIndex, - world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, - LocalEntityAndGlobalEntityConverter, MessageContainer, -}; + message_kinds::MessageKinds, +}, sequence_greater_than, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind}; pub struct SequencedUnreliableReceiver { newest_received_message_index: Option, @@ -65,6 +60,7 @@ impl SequencedUnreliableReceiver { impl ChannelReceiver for SequencedUnreliableReceiver { fn receive_messages( &mut self, + _message_kinds: &MessageKinds, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec { @@ -95,4 +91,8 @@ impl MessageChannelReceiver for SequencedUnreliableReceiver { } Ok(()) } + + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)> { + panic!("SequencedUnreliable channels do not support requests"); + } } diff --git a/shared/src/messages/channels/receivers/unordered_reliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_reliable_receiver.rs index 559a72cbc..dd8a6ae67 100644 --- a/shared/src/messages/channels/receivers/unordered_reliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_reliable_receiver.rs @@ -20,10 +20,11 @@ pub struct UnorderedArranger; impl ReceiverArranger for UnorderedArranger { fn process( &mut self, - incoming_messages: &mut Vec<(MessageIndex, MessageContainer)>, message_index: MessageIndex, message: MessageContainer, - ) { - incoming_messages.push((message_index, message)); + ) -> Vec<(MessageIndex, MessageContainer)> { + let mut output = Vec::new(); + output.push((message_index, message)); + output } } diff --git a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs index aaebfb2b2..008fde129 100644 --- a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs @@ -2,14 +2,10 @@ use std::{collections::VecDeque, mem}; use naia_serde::{BitReader, Serde, SerdeErr}; -use crate::{ - messages::{ - channels::receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, - message_kinds::MessageKinds, - }, - world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, - LocalEntityAndGlobalEntityConverter, MessageContainer, -}; +use crate::{messages::{local_request_sender::LocalRequestId, + channels::receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, + message_kinds::MessageKinds, +}, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind}; pub struct UnorderedUnreliableReceiver { incoming_messages: VecDeque, @@ -47,6 +43,7 @@ impl UnorderedUnreliableReceiver { impl ChannelReceiver for UnorderedUnreliableReceiver { fn receive_messages( &mut self, + _message_kinds: &MessageKinds, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec { @@ -81,4 +78,8 @@ impl MessageChannelReceiver for UnorderedUnreliableReceiver { Ok(()) } + + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)> { + panic!("UnorderedUnreliable channels do not support requests"); + } } diff --git a/shared/src/messages/channels/senders/channel_sender.rs b/shared/src/messages/channels/senders/channel_sender.rs index f04a1f2d0..b3b55657d 100644 --- a/shared/src/messages/channels/senders/channel_sender.rs +++ b/shared/src/messages/channels/senders/channel_sender.rs @@ -1,11 +1,7 @@ use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{ - messages::{message_container::MessageContainer, message_kinds::MessageKinds}, - types::MessageIndex, - LocalEntityAndGlobalEntityConverterMut, -}; +use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId}; pub trait ChannelSender

: Send + Sync { /// Queues a Message to be transmitted to the remote host into an internal buffer @@ -27,4 +23,7 @@ pub trait MessageChannelSender: ChannelSender { writer: &mut BitWriter, has_written: &mut bool, ) -> Option>; + + /// Queues a Request to be transmitted to the remote host into an internal buffer + fn send_request(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, global_request_id: GlobalRequestId, request: MessageContainer); } diff --git a/shared/src/messages/channels/senders/mod.rs b/shared/src/messages/channels/senders/mod.rs index de97a22f2..2836aa59e 100644 --- a/shared/src/messages/channels/senders/mod.rs +++ b/shared/src/messages/channels/senders/mod.rs @@ -2,5 +2,6 @@ pub mod channel_sender; pub mod indexed_message_writer; pub mod message_fragmenter; pub mod reliable_sender; +pub mod reliable_message_sender; pub mod sequenced_unreliable_sender; pub mod unordered_unreliable_sender; diff --git a/shared/src/messages/channels/senders/reliable_message_sender.rs b/shared/src/messages/channels/senders/reliable_message_sender.rs new file mode 100644 index 000000000..7f26fdc59 --- /dev/null +++ b/shared/src/messages/channels/senders/reliable_message_sender.rs @@ -0,0 +1,80 @@ + +use naia_serde::BitWriter; +use naia_socket_shared::Instant; + +use crate::{messages::{ + local_request_sender::LocalRequestSender, + channels::senders::{ + channel_sender::{ChannelSender, MessageChannelSender}, + indexed_message_writer::IndexedMessageWriter, + }, + message_container::MessageContainer, + message_kinds::MessageKinds, +}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId, ReliableSender}; + +// Sender +pub struct ReliableMessageSender { + reliable_sender: ReliableSender, + request_sender: LocalRequestSender, +} + +impl ReliableMessageSender { + pub fn new(rtt_resend_factor: f32) -> Self { + Self { + reliable_sender: ReliableSender::new(rtt_resend_factor), + request_sender: LocalRequestSender::new(), + } + } +} + +impl ChannelSender for ReliableMessageSender { + fn send_message(&mut self, message: MessageContainer) { + self.reliable_sender.send_message(message); + } + + fn collect_messages(&mut self, now: &Instant, rtt_millis: &f32) { + self.reliable_sender.collect_messages(now, rtt_millis); + } + + fn has_messages(&self) -> bool { + self.reliable_sender.has_messages() + } + + fn notify_message_delivered(&mut self, message_index: &MessageIndex) { + self.reliable_sender.notify_message_delivered(message_index); + } +} + +impl MessageChannelSender for ReliableMessageSender { + fn write_messages( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + writer: &mut BitWriter, + has_written: &mut bool, + ) -> Option> { + IndexedMessageWriter::write_messages( + message_kinds, + &mut self.reliable_sender.outgoing_messages, + converter, + writer, + has_written, + ) + } + + fn send_request( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + global_request_id: GlobalRequestId, + request: MessageContainer + ) { + let processed_request = self.request_sender.process_request( + message_kinds, + converter, + global_request_id, + request, + ); + self.send_message(processed_request); + } +} diff --git a/shared/src/messages/channels/senders/reliable_sender.rs b/shared/src/messages/channels/senders/reliable_sender.rs index 40654cd33..81d1ce04f 100644 --- a/shared/src/messages/channels/senders/reliable_sender.rs +++ b/shared/src/messages/channels/senders/reliable_sender.rs @@ -1,27 +1,18 @@ use std::{collections::VecDeque, mem, time::Duration}; -use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{ - messages::{ - channels::senders::{ - channel_sender::{ChannelSender, MessageChannelSender}, - indexed_message_writer::IndexedMessageWriter, - }, - message_container::MessageContainer, - message_kinds::MessageKinds, - }, - types::MessageIndex, - LocalEntityAndGlobalEntityConverterMut, -}; +use crate::{messages:: + channels::senders:: + channel_sender::ChannelSender, + types::MessageIndex}; // Sender pub struct ReliableSender { rtt_resend_factor: f32, sending_messages: VecDeque, P)>>, next_send_message_index: MessageIndex, - outgoing_messages: VecDeque<(MessageIndex, P)>, + pub(crate) outgoing_messages: VecDeque<(MessageIndex, P)>, } impl ReliableSender

{ @@ -123,22 +114,4 @@ impl ChannelSender

for ReliableSender

{ fn notify_message_delivered(&mut self, message_index: &MessageIndex) { self.deliver_message(message_index); } -} - -impl MessageChannelSender for ReliableSender { - fn write_messages( - &mut self, - message_kinds: &MessageKinds, - converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, - writer: &mut BitWriter, - has_written: &mut bool, - ) -> Option> { - IndexedMessageWriter::write_messages( - message_kinds, - &mut self.outgoing_messages, - converter, - writer, - has_written, - ) - } -} +} \ No newline at end of file diff --git a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs index 94717a8ad..ca7495724 100644 --- a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs @@ -3,18 +3,14 @@ use std::collections::VecDeque; use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{ - messages::{ - channels::senders::{ - channel_sender::{ChannelSender, MessageChannelSender}, - indexed_message_writer::IndexedMessageWriter, - }, - message_container::MessageContainer, - message_kinds::MessageKinds, +use crate::{messages::{ + channels::senders::{ + channel_sender::{ChannelSender, MessageChannelSender}, + indexed_message_writer::IndexedMessageWriter, }, - types::MessageIndex, - LocalEntityAndGlobalEntityConverterMut, -}; + message_container::MessageContainer, + message_kinds::MessageKinds, +}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId}; pub struct SequencedUnreliableSender { /// Buffer of the next messages to send along with their MessageKind @@ -70,4 +66,8 @@ impl MessageChannelSender for SequencedUnreliableSender { has_written, ) } + + fn send_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + panic!("SequencedUnreliable channel does not support requests"); + } } diff --git a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs index 249c0292a..465fff4d8 100644 --- a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs @@ -3,15 +3,11 @@ use std::collections::VecDeque; use naia_serde::{BitWrite, BitWriter, Serde}; use naia_socket_shared::Instant; -use crate::{ - messages::{ - channels::senders::channel_sender::{ChannelSender, MessageChannelSender}, - message_container::MessageContainer, - message_kinds::MessageKinds, - }, - types::MessageIndex, - LocalEntityAndGlobalEntityConverterMut, -}; +use crate::{messages::{ + channels::senders::channel_sender::{ChannelSender, MessageChannelSender}, + message_container::MessageContainer, + message_kinds::MessageKinds, +}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId}; pub struct UnorderedUnreliableSender { outgoing_messages: VecDeque, @@ -103,4 +99,8 @@ impl MessageChannelSender for UnorderedUnreliableSender { } None } + + fn send_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + panic!("UnorderedUnreliable channel does not support requests"); + } } diff --git a/shared/src/messages/local_request_sender.rs b/shared/src/messages/local_request_sender.rs new file mode 100644 index 000000000..6ed4dee6d --- /dev/null +++ b/shared/src/messages/local_request_sender.rs @@ -0,0 +1,124 @@ +use std::{time::Duration, collections::HashMap}; + +use naia_derive::MessageRequest; +use naia_serde::{BitReader, BitWrite, BitWriter, Serde, SerdeErr}; + +use crate::{types::GlobalRequestId, KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKind, MessageKinds}; + +pub struct LocalRequestSender { + channels: HashMap, +} + +impl LocalRequestSender { + pub fn new() -> Self { + Self { + channels: HashMap::new(), + } + } + + pub(crate) fn process_request( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + global_request_id: GlobalRequestId, + request: MessageContainer + ) -> MessageContainer { + let key = request.kind(); + if !self.channels.contains_key(&key) { + self.channels.insert(key.clone(), LocalRequestSenderChannel::new()); + } + let channel = self.channels.get_mut(&key).unwrap(); + channel.process_request(message_kinds, converter, global_request_id, request) + } +} + +pub struct LocalRequestSenderChannel { + local_key_generator: KeyGenerator, + local_to_global_ids: HashMap, +} + +impl LocalRequestSenderChannel { + pub fn new() -> Self { + Self { + local_key_generator: KeyGenerator::new(Duration::from_secs(60)), + local_to_global_ids: HashMap::new(), + } + } + + pub(crate) fn process_request( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + global_request_id: GlobalRequestId, + request: MessageContainer + ) -> MessageContainer { + + let request_key = self.local_key_generator.generate(); + self.local_to_global_ids.insert(request_key, global_request_id); + + let mut writer = BitWriter::with_max_capacity(); + request.write(message_kinds, &mut writer, converter); + let request_bytes = writer.to_bytes(); + let request_message = RequestMessage::new(request_key, request_bytes); + MessageContainer::from_write(Box::new(request_message), converter) + } +} + +#[derive(MessageRequest)] +pub struct RequestMessage { + request_id: LocalRequestId, + bytes: Box<[u8]>, +} + +impl RequestMessage { + pub fn new(request_id: LocalRequestId, bytes: Box<[u8]>) -> Self { + Self { + request_id, + bytes, + } + } + + pub(crate) fn to_id_and_bytes(self) -> (LocalRequestId, Box<[u8]>) { + (self.request_id, self.bytes) + } +} + +pub type LocalResponseId = LocalRequestId; + +#[derive(Clone, Copy, Eq, Hash, PartialEq)] +pub struct LocalRequestId { + id: u8, +} + +impl LocalRequestId { + pub(crate) fn new(id: u8) -> Self { + Self { id } + } +} + +impl From for LocalRequestId { + fn from(id: u16) -> Self { + Self { id: id as u8 } + } +} + +impl Into for LocalRequestId { + fn into(self) -> u16 { + self.id as u16 + } +} + +impl Serde for LocalRequestId { + fn ser(&self, writer: &mut dyn BitWrite) { + self.id.ser(writer) + } + + fn de(reader: &mut BitReader) -> Result { + let id = u8::de(reader)?; + Ok(Self { id }) + } + + fn bit_length(&self) -> u32 { + self.id.bit_length() + } +} \ No newline at end of file diff --git a/shared/src/messages/message.rs b/shared/src/messages/message.rs index 488b99d46..a0698d327 100644 --- a/shared/src/messages/message.rs +++ b/shared/src/messages/message.rs @@ -31,6 +31,7 @@ pub trait Message: Send + Sync + Named + MessageClone + Any { Self: Sized; fn bit_length(&self, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut) -> u32; fn is_fragment(&self) -> bool; + fn is_request(&self) -> bool; /// Writes data into an outgoing byte stream fn write( &self, diff --git a/shared/src/messages/message_container.rs b/shared/src/messages/message_container.rs index b673682c8..aecf5e0b9 100644 --- a/shared/src/messages/message_container.rs +++ b/shared/src/messages/message_container.rs @@ -59,6 +59,10 @@ impl MessageContainer { return self.inner.is_fragment(); } + pub fn is_request(&self) -> bool { + return self.inner.is_request(); + } + pub fn to_boxed_any(self) -> Box { return self.inner.to_boxed_any(); } diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index 93d904688..b864b37e9 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -1,10 +1,10 @@ -use std::collections::HashMap; -use std::hash::Hash; +use std::{hash::Hash, collections::HashMap}; use naia_serde::{BitReader, BitWrite, BitWriter, ConstBitLength, Serde, SerdeErr}; use naia_socket_shared::Instant; use crate::{constants::FRAGMENTATION_LIMIT_BITS, messages::{ + local_request_sender::LocalRequestId, channels::{ channel::ChannelMode, channel::ChannelSettings, @@ -18,17 +18,17 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, messages::{ unordered_unreliable_receiver::UnorderedUnreliableReceiver, }, senders::{ + reliable_message_sender::ReliableMessageSender, channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, - reliable_sender::ReliableSender, sequenced_unreliable_sender::SequencedUnreliableSender, unordered_unreliable_sender::UnorderedUnreliableSender, }, }, message_container::MessageContainer, -}, types::{HostType, MessageIndex, PacketIndex}, world::{ +}, types::{GlobalRequestId, HostType, MessageIndex, PacketIndex}, world::{ entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, remote::entity_waitlist::EntityWaitlist, -}, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, Protocol}; +}, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, Protocol, MessageKind}; /// Handles incoming/outgoing messages, tracks the delivery status of Messages /// so that guaranteed Messages can be re-transmitted to the remote host @@ -75,7 +75,7 @@ impl MessageManager { | ChannelMode::OrderedReliable(settings) => { channel_senders.insert( channel_kind, - Box::new(ReliableSender::::new( + Box::new(ReliableMessageSender::new( settings.rtt_resend_factor, )), ); @@ -145,7 +145,7 @@ impl MessageManager { channel_settings_map.insert(channel_kind.clone(), channel_settings); } - MessageManager { + Self { channel_senders, channel_receivers, channel_settings: channel_settings_map, @@ -194,10 +194,13 @@ impl MessageManager { message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, channel_kind: &ChannelKind, - global_request_id: u64, + global_request_id: GlobalRequestId, request: MessageContainer ) { - todo!() + let Some(channel) = self.channel_senders.get_mut(channel_kind) else { + panic!("Channel not configured correctly! Cannot send message."); + }; + channel.send_request(message_kinds, converter, global_request_id, request); } pub fn send_response( @@ -205,7 +208,7 @@ impl MessageManager { message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, channel_kind: &ChannelKind, - global_request_id: u64, + global_request_id: GlobalRequestId, response: MessageContainer ) { todo!() @@ -311,6 +314,7 @@ impl MessageManager { /// Retrieve all messages from the channel buffers pub fn receive_messages( &mut self, + message_kinds: &MessageKinds, global_entity_converter: &dyn EntityAndGlobalEntityConverter, local_entity_converter: &dyn EntityAndLocalEntityConverter, entity_waitlist: &mut EntityWaitlist, @@ -320,11 +324,23 @@ impl MessageManager { let mut output = Vec::new(); // TODO: shouldn't we have a priority mechanisms between channels? for (channel_kind, channel) in &mut self.channel_receivers { - let messages = channel.receive_messages(entity_waitlist, &entity_converter); + let messages = channel.receive_messages(message_kinds, entity_waitlist, &entity_converter); output.push((channel_kind.clone(), messages)); } output } + + /// Retrieve all requests from the channel buffers + pub fn receive_requests( + &mut self, + ) -> Vec<(ChannelKind, Vec<(MessageKind, LocalRequestId, MessageContainer)>)> { + let mut output = Vec::new(); + for (channel_kind, channel) in &mut self.channel_receivers { + let requests = channel.receive_requests(); + output.push((channel_kind.clone(), requests)); + } + output + } } impl MessageManager { diff --git a/shared/src/messages/mod.rs b/shared/src/messages/mod.rs index 2582bd3f8..bc545dc1c 100644 --- a/shared/src/messages/mod.rs +++ b/shared/src/messages/mod.rs @@ -6,7 +6,9 @@ pub mod message_kinds; pub mod message_manager; pub mod named; pub mod request; +pub mod local_request_sender; #[cfg(test)] mod tests; + diff --git a/shared/src/messages/request.rs b/shared/src/messages/request.rs index f9ef3e0e8..a445a47b3 100644 --- a/shared/src/messages/request.rs +++ b/shared/src/messages/request.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use crate::Message; +use crate::{Message, types::GlobalRequestId}; // Request pub trait Request: Message { @@ -13,19 +13,19 @@ pub trait Response: Message {} // ResponseSendKey #[derive(Clone, Eq, PartialEq, Hash)] pub struct ResponseSendKey { - request_id: u64, + request_id: GlobalRequestId, phantom_s: PhantomData, } impl ResponseSendKey { - pub fn new(id: u64) -> Self { + pub fn new(id: GlobalRequestId) -> Self { Self { request_id: id, phantom_s: PhantomData, } } - pub fn request_id(&self) -> u64 { + pub fn request_id(&self) -> GlobalRequestId { self.request_id } } @@ -33,19 +33,19 @@ impl ResponseSendKey { // ResponseReceiveKey #[derive(Clone, Eq, PartialEq, Hash)] pub struct ResponseReceiveKey { - response_id: u64, + response_id: GlobalRequestId, phantom_s: PhantomData, } impl ResponseReceiveKey { - pub fn new(request_id: u64) -> Self { + pub fn new(request_id: GlobalRequestId) -> Self { Self { response_id: request_id, phantom_s: PhantomData, } } - pub fn response_id(&self) -> u64 { + pub fn response_id(&self) -> GlobalRequestId { self.response_id } } \ No newline at end of file diff --git a/shared/src/types.rs b/shared/src/types.rs index 437db17b3..4ce557af2 100644 --- a/shared/src/types.rs +++ b/shared/src/types.rs @@ -2,9 +2,11 @@ pub type PacketIndex = u16; pub type Tick = u16; pub type MessageIndex = u16; pub type ShortMessageIndex = u8; +pub type GlobalRequestId = u64; +pub type GlobalResponseId = u64; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum HostType { Server, Client, -} +} \ No newline at end of file From b229293e079bb41d2af6b4540a0451f7b82dd551 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 5 Feb 2024 20:41:09 -0600 Subject: [PATCH 23/99] renames --- demos/bevy/server/src/systems/events.rs | 2 +- shared/src/lib.rs | 16 ++++++++-------- .../channels/receivers/channel_receiver.rs | 3 ++- .../receivers/reliable_message_receiver.rs | 6 +++--- .../receivers/sequenced_unreliable_receiver.rs | 6 +++--- .../receivers/unordered_unreliable_receiver.rs | 5 +++-- shared/src/messages/channels/senders/mod.rs | 1 + .../channels/senders/reliable_message_sender.rs | 10 +++++----- .../senders/request_sender.rs} | 12 ++++++------ shared/src/messages/message_manager.rs | 14 +++++++------- shared/src/messages/mod.rs | 1 - shared/src/protocol.rs | 3 ++- 12 files changed, 41 insertions(+), 38 deletions(-) rename shared/src/messages/{local_request_sender.rs => channels/senders/request_sender.rs} (91%) diff --git a/demos/bevy/server/src/systems/events.rs b/demos/bevy/server/src/systems/events.rs index 7aed61866..db08355c0 100644 --- a/demos/bevy/server/src/systems/events.rs +++ b/demos/bevy/server/src/systems/events.rs @@ -179,7 +179,7 @@ pub fn request_events( ) { for events in event_reader.read() { for (user_key, response_send_key, basic_request) in events.read::() { - + todo!() } } } diff --git a/shared/src/lib.rs b/shared/src/lib.rs index a8baa7039..18884e838 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -24,13 +24,13 @@ pub use naia_derive::{ Channel, Message, MessageBevy, MessageHecs, Replicate, ReplicateBevy, ReplicateHecs, }; pub use naia_serde::{ - BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, OutgoingPacket, OwnedBitReader, - Serde, SerdeBevyClient, SerdeBevyServer, SerdeBevyShared, SerdeErr, SerdeHecs, - SerdeIntegerConversion, SerdeInternal, SignedInteger, SignedVariableInteger, UnsignedInteger, - UnsignedVariableInteger, MTU_SIZE_BITS, MTU_SIZE_BYTES, + BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, MTU_SIZE_BITS, MTU_SIZE_BYTES, + OutgoingPacket, OwnedBitReader, Serde, SerdeBevyClient, SerdeBevyServer, SerdeBevyShared, + SerdeErr, SerdeHecs, SerdeIntegerConversion, SerdeInternal, SignedInteger, + SignedVariableInteger, UnsignedInteger, UnsignedVariableInteger, }; pub use naia_socket_shared::{ - link_condition_logic, Instant, LinkConditionerConfig, Random, SocketConfig, TimeQueue, + Instant, link_condition_logic, LinkConditionerConfig, Random, SocketConfig, TimeQueue, }; mod backends; @@ -81,7 +81,6 @@ pub use messages::{ message_manager::MessageManager, named::Named, request::{Request, Response, ResponseReceiveKey, ResponseSendKey}, - local_request_sender::{RequestMessage, LocalResponseId}, }; pub use world::{ component::{ @@ -135,8 +134,9 @@ pub use world::{ }; pub use bigmap::{BigMap, BigMapKey}; -pub use game_time::{GameDuration, GameInstant, GAME_TIME_LIMIT}; +pub use game_time::{GAME_TIME_LIMIT, GameDuration, GameInstant}; pub use key_generator::KeyGenerator; +pub use messages::channels::senders::request_sender::{LocalResponseId, RequestMessage}; pub use protocol::{Protocol, ProtocolPlugin}; -pub use types::{HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick, GlobalRequestId, GlobalResponseId}; +pub use types::{GlobalRequestId, GlobalResponseId, HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick}; pub use wrapping_number::{sequence_greater_than, sequence_less_than, wrapping_diff}; diff --git a/shared/src/messages/channels/receivers/channel_receiver.rs b/shared/src/messages/channels/receivers/channel_receiver.rs index 38cfcd6f0..5cb8ed8b1 100644 --- a/shared/src/messages/channels/receivers/channel_receiver.rs +++ b/shared/src/messages/channels/receivers/channel_receiver.rs @@ -1,6 +1,7 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds, local_request_sender::LocalRequestId}, world::remote::entity_waitlist::EntityWaitlist, LocalEntityAndGlobalEntityConverter, MessageKind}; +use crate::{LocalEntityAndGlobalEntityConverter, MessageKind, messages::{message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; +use crate::messages::channels::senders::request_sender::LocalRequestId; pub trait ChannelReceiver

: Send + Sync { /// Read messages from an internal buffer and return their content diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index 95740052c..609b6316c 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -1,7 +1,6 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{messages::{ - local_request_sender::LocalRequestId, +use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ channels::receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, fragment_receiver::FragmentReceiver, @@ -9,7 +8,8 @@ use crate::{messages::{ reliable_receiver::ReliableReceiver, }, message_kinds::MessageKinds, -}, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, RequestMessage}; +}, RequestMessage, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; +use crate::messages::channels::senders::request_sender::LocalRequestId; // Receiver Arranger Trait pub trait ReceiverArranger: Send + Sync { diff --git a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs index b6696eb0a..af757488a 100644 --- a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs @@ -2,14 +2,14 @@ use std::mem; use naia_serde::{BitReader, SerdeErr}; -use crate::{messages::{ - local_request_sender::LocalRequestId, +use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ channels::receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, indexed_message_reader::IndexedMessageReader, }, message_kinds::MessageKinds, -}, sequence_greater_than, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind}; +}, sequence_greater_than, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; +use crate::messages::channels::senders::request_sender::LocalRequestId; pub struct SequencedUnreliableReceiver { newest_received_message_index: Option, diff --git a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs index 008fde129..f3ca13ad6 100644 --- a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs @@ -2,10 +2,11 @@ use std::{collections::VecDeque, mem}; use naia_serde::{BitReader, Serde, SerdeErr}; -use crate::{messages::{local_request_sender::LocalRequestId, +use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ channels::receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, message_kinds::MessageKinds, -}, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind}; +}, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; +use crate::messages::channels::senders::request_sender::LocalRequestId; pub struct UnorderedUnreliableReceiver { incoming_messages: VecDeque, diff --git a/shared/src/messages/channels/senders/mod.rs b/shared/src/messages/channels/senders/mod.rs index 2836aa59e..0024dbac8 100644 --- a/shared/src/messages/channels/senders/mod.rs +++ b/shared/src/messages/channels/senders/mod.rs @@ -5,3 +5,4 @@ pub mod reliable_sender; pub mod reliable_message_sender; pub mod sequenced_unreliable_sender; pub mod unordered_unreliable_sender; +pub mod request_sender; diff --git a/shared/src/messages/channels/senders/reliable_message_sender.rs b/shared/src/messages/channels/senders/reliable_message_sender.rs index 7f26fdc59..37d0de070 100644 --- a/shared/src/messages/channels/senders/reliable_message_sender.rs +++ b/shared/src/messages/channels/senders/reliable_message_sender.rs @@ -2,27 +2,27 @@ use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{messages::{ - local_request_sender::LocalRequestSender, +use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverterMut, messages::{ channels::senders::{ channel_sender::{ChannelSender, MessageChannelSender}, indexed_message_writer::IndexedMessageWriter, }, message_container::MessageContainer, message_kinds::MessageKinds, -}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId, ReliableSender}; +}, ReliableSender, types::MessageIndex}; +use crate::messages::channels::senders::request_sender::RequestSender; // Sender pub struct ReliableMessageSender { reliable_sender: ReliableSender, - request_sender: LocalRequestSender, + request_sender: RequestSender, } impl ReliableMessageSender { pub fn new(rtt_resend_factor: f32) -> Self { Self { reliable_sender: ReliableSender::new(rtt_resend_factor), - request_sender: LocalRequestSender::new(), + request_sender: RequestSender::new(), } } } diff --git a/shared/src/messages/local_request_sender.rs b/shared/src/messages/channels/senders/request_sender.rs similarity index 91% rename from shared/src/messages/local_request_sender.rs rename to shared/src/messages/channels/senders/request_sender.rs index 6ed4dee6d..e1db443a9 100644 --- a/shared/src/messages/local_request_sender.rs +++ b/shared/src/messages/channels/senders/request_sender.rs @@ -5,11 +5,11 @@ use naia_serde::{BitReader, BitWrite, BitWriter, Serde, SerdeErr}; use crate::{types::GlobalRequestId, KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKind, MessageKinds}; -pub struct LocalRequestSender { - channels: HashMap, +pub struct RequestSender { + channels: HashMap, } -impl LocalRequestSender { +impl RequestSender { pub fn new() -> Self { Self { channels: HashMap::new(), @@ -25,19 +25,19 @@ impl LocalRequestSender { ) -> MessageContainer { let key = request.kind(); if !self.channels.contains_key(&key) { - self.channels.insert(key.clone(), LocalRequestSenderChannel::new()); + self.channels.insert(key.clone(), RequestSenderChannel::new()); } let channel = self.channels.get_mut(&key).unwrap(); channel.process_request(message_kinds, converter, global_request_id, request) } } -pub struct LocalRequestSenderChannel { +pub struct RequestSenderChannel { local_key_generator: KeyGenerator, local_to_global_ids: HashMap, } -impl LocalRequestSenderChannel { +impl RequestSenderChannel { pub fn new() -> Self { Self { local_key_generator: KeyGenerator::new(Duration::from_secs(60)), diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index b864b37e9..cb63f19cf 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -1,10 +1,9 @@ -use std::{hash::Hash, collections::HashMap}; +use std::{collections::HashMap, hash::Hash}; use naia_serde::{BitReader, BitWrite, BitWriter, ConstBitLength, Serde, SerdeErr}; use naia_socket_shared::Instant; -use crate::{constants::FRAGMENTATION_LIMIT_BITS, messages::{ - local_request_sender::LocalRequestId, +use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKind, MessageKinds, messages::{ channels::{ channel::ChannelMode, channel::ChannelSettings, @@ -18,17 +17,18 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, messages::{ unordered_unreliable_receiver::UnorderedUnreliableReceiver, }, senders::{ - reliable_message_sender::ReliableMessageSender, - channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, + channel_sender::MessageChannelSender, + message_fragmenter::MessageFragmenter, reliable_message_sender::ReliableMessageSender, sequenced_unreliable_sender::SequencedUnreliableSender, unordered_unreliable_sender::UnorderedUnreliableSender, }, }, message_container::MessageContainer, -}, types::{GlobalRequestId, HostType, MessageIndex, PacketIndex}, world::{ +}, Protocol, types::{GlobalRequestId, HostType, MessageIndex, PacketIndex}, world::{ entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, remote::entity_waitlist::EntityWaitlist, -}, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, Protocol, MessageKind}; +}}; +use crate::messages::channels::senders::request_sender::LocalRequestId; /// Handles incoming/outgoing messages, tracks the delivery status of Messages /// so that guaranteed Messages can be re-transmitted to the remote host diff --git a/shared/src/messages/mod.rs b/shared/src/messages/mod.rs index bc545dc1c..843c866da 100644 --- a/shared/src/messages/mod.rs +++ b/shared/src/messages/mod.rs @@ -6,7 +6,6 @@ pub mod message_kinds; pub mod message_manager; pub mod named; pub mod request; -pub mod local_request_sender; #[cfg(test)] mod tests; diff --git a/shared/src/protocol.rs b/shared/src/protocol.rs index 8ace859e2..6f9f40731 100644 --- a/shared/src/protocol.rs +++ b/shared/src/protocol.rs @@ -12,7 +12,7 @@ use crate::{connection::compression_config::CompressionConfig, messages::{ fragment::FragmentedMessage, message::Message, message_kinds::MessageKinds, -}, world::component::{component_kinds::ComponentKinds, replicate::Replicate}, EntityEventMessage, ReliableSettings, Request}; +}, world::component::{component_kinds::ComponentKinds, replicate::Replicate}, EntityEventMessage, ReliableSettings, Request, RequestMessage}; // Protocol Plugin pub trait ProtocolPlugin { @@ -39,6 +39,7 @@ impl Default for Protocol { fn default() -> Self { let mut message_kinds = MessageKinds::new(); message_kinds.add_message::(); + message_kinds.add_message::(); message_kinds.add_message::(); let mut channel_kinds = ChannelKinds::new(); From 1895c1b92a0806683a130b9443fa526c02f74c07 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 5 Feb 2024 20:46:41 -0600 Subject: [PATCH 24/99] more renaming --- client/src/request.rs | 4 +-- server/src/request.rs | 4 +-- shared/src/lib.rs | 2 +- .../channels/receivers/channel_receiver.rs | 5 ++- .../receivers/reliable_message_receiver.rs | 13 ++++---- .../sequenced_unreliable_receiver.rs | 7 ++-- .../unordered_unreliable_receiver.rs | 5 ++- .../channels/senders/request_sender.rs | 32 +++++++++---------- shared/src/messages/message_manager.rs | 4 +-- shared/src/protocol.rs | 4 +-- 10 files changed, 37 insertions(+), 43 deletions(-) diff --git a/client/src/request.rs b/client/src/request.rs index 693063435..7d951c070 100644 --- a/client/src/request.rs +++ b/client/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer, MessageKind}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestResponseId, MessageContainer, MessageKind}; // GlobalRequestManager pub struct GlobalRequestManager { @@ -33,7 +33,7 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_response_id: &LocalResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_req_res_id: &LocalRequestResponseId) -> GlobalResponseId { todo!() } diff --git a/server/src/request.rs b/server/src/request.rs index 6b5a780cd..3ecf95ace 100644 --- a/server/src/request.rs +++ b/server/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer, MessageKind}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestResponseId, MessageContainer, MessageKind}; use crate::UserKey; @@ -35,7 +35,7 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_request_id: &LocalResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_req_res_id: &LocalRequestResponseId) -> GlobalResponseId { todo!() } diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 18884e838..d5d737da8 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -136,7 +136,7 @@ pub use world::{ pub use bigmap::{BigMap, BigMapKey}; pub use game_time::{GAME_TIME_LIMIT, GameDuration, GameInstant}; pub use key_generator::KeyGenerator; -pub use messages::channels::senders::request_sender::{LocalResponseId, RequestMessage}; +pub use messages::channels::senders::request_sender::{LocalRequestResponseId, RequestOrResponse}; pub use protocol::{Protocol, ProtocolPlugin}; pub use types::{GlobalRequestId, GlobalResponseId, HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick}; pub use wrapping_number::{sequence_greater_than, sequence_less_than, wrapping_diff}; diff --git a/shared/src/messages/channels/receivers/channel_receiver.rs b/shared/src/messages/channels/receivers/channel_receiver.rs index 5cb8ed8b1..a53965e47 100644 --- a/shared/src/messages/channels/receivers/channel_receiver.rs +++ b/shared/src/messages/channels/receivers/channel_receiver.rs @@ -1,7 +1,6 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, MessageKind, messages::{message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; -use crate::messages::channels::senders::request_sender::LocalRequestId; +use crate::{LocalEntityAndGlobalEntityConverter, MessageKind, messages::{channels::senders::request_sender::LocalRequestResponseId, message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; pub trait ChannelReceiver

: Send + Sync { /// Read messages from an internal buffer and return their content @@ -23,5 +22,5 @@ pub trait MessageChannelReceiver: ChannelReceiver { reader: &mut BitReader, ) -> Result<(), SerdeErr>; - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)>; + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)>; } diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index 609b6316c..dbeea2dfc 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -1,15 +1,14 @@ use naia_serde::{BitReader, SerdeErr}; use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ - channels::receivers::{ + channels::{receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, fragment_receiver::FragmentReceiver, indexed_message_reader::IndexedMessageReader, reliable_receiver::ReliableReceiver, - }, + }, senders::request_sender::LocalRequestResponseId}, message_kinds::MessageKinds, -}, RequestMessage, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; -use crate::messages::channels::senders::request_sender::LocalRequestId; +}, RequestOrResponse, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; // Receiver Arranger Trait pub trait ReceiverArranger: Send + Sync { @@ -28,7 +27,7 @@ pub struct ReliableMessageReceiver { fragment_receiver: FragmentReceiver, waitlist_store: WaitlistStore<(MessageIndex, MessageContainer)>, current_index: MessageIndex, - incoming_requests: Vec<(MessageKind, LocalRequestId, MessageContainer)>, + incoming_requests: Vec<(MessageKind, LocalRequestResponseId, MessageContainer)>, } impl ReliableMessageReceiver { @@ -110,7 +109,7 @@ impl ReliableMessageReceiver { // it is! cast it let request_container = message_container .to_boxed_any() - .downcast::() + .downcast::() .unwrap(); let (local_request_id, request_bytes) = request_container.to_id_and_bytes(); let mut reader = BitReader::new(&request_bytes); @@ -167,7 +166,7 @@ impl MessageChannelReceiver for ReliableMessageReceiver Ok(()) } - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)> { + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)> { std::mem::take(&mut self.incoming_requests) } } diff --git a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs index af757488a..efb6d674c 100644 --- a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs @@ -3,13 +3,12 @@ use std::mem; use naia_serde::{BitReader, SerdeErr}; use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ - channels::receivers::{ + channels::{receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, indexed_message_reader::IndexedMessageReader, - }, + }, senders::request_sender::LocalRequestResponseId}, message_kinds::MessageKinds, }, sequence_greater_than, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; -use crate::messages::channels::senders::request_sender::LocalRequestId; pub struct SequencedUnreliableReceiver { newest_received_message_index: Option, @@ -92,7 +91,7 @@ impl MessageChannelReceiver for SequencedUnreliableReceiver { Ok(()) } - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)> { + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)> { panic!("SequencedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs index f3ca13ad6..5fa5d381c 100644 --- a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs @@ -3,10 +3,9 @@ use std::{collections::VecDeque, mem}; use naia_serde::{BitReader, Serde, SerdeErr}; use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ - channels::receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, + channels::{receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, senders::request_sender::LocalRequestResponseId}, message_kinds::MessageKinds, }, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; -use crate::messages::channels::senders::request_sender::LocalRequestId; pub struct UnorderedUnreliableReceiver { incoming_messages: VecDeque, @@ -80,7 +79,7 @@ impl MessageChannelReceiver for UnorderedUnreliableReceiver { Ok(()) } - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestId, MessageContainer)> { + fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)> { panic!("UnorderedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/senders/request_sender.rs b/shared/src/messages/channels/senders/request_sender.rs index e1db443a9..a33bd2c59 100644 --- a/shared/src/messages/channels/senders/request_sender.rs +++ b/shared/src/messages/channels/senders/request_sender.rs @@ -33,8 +33,8 @@ impl RequestSender { } pub struct RequestSenderChannel { - local_key_generator: KeyGenerator, - local_to_global_ids: HashMap, + local_key_generator: KeyGenerator, + local_to_global_ids: HashMap, } impl RequestSenderChannel { @@ -59,56 +59,54 @@ impl RequestSenderChannel { let mut writer = BitWriter::with_max_capacity(); request.write(message_kinds, &mut writer, converter); let request_bytes = writer.to_bytes(); - let request_message = RequestMessage::new(request_key, request_bytes); + let request_message = RequestOrResponse::new(request_key, request_bytes); MessageContainer::from_write(Box::new(request_message), converter) } } #[derive(MessageRequest)] -pub struct RequestMessage { - request_id: LocalRequestId, +pub struct RequestOrResponse { + id: LocalRequestResponseId, bytes: Box<[u8]>, } -impl RequestMessage { - pub fn new(request_id: LocalRequestId, bytes: Box<[u8]>) -> Self { +impl RequestOrResponse { + pub fn new(request_id: LocalRequestResponseId, bytes: Box<[u8]>) -> Self { Self { - request_id, + id: request_id, bytes, } } - pub(crate) fn to_id_and_bytes(self) -> (LocalRequestId, Box<[u8]>) { - (self.request_id, self.bytes) + pub(crate) fn to_id_and_bytes(self) -> (LocalRequestResponseId, Box<[u8]>) { + (self.id, self.bytes) } } -pub type LocalResponseId = LocalRequestId; - #[derive(Clone, Copy, Eq, Hash, PartialEq)] -pub struct LocalRequestId { +pub struct LocalRequestResponseId { id: u8, } -impl LocalRequestId { +impl LocalRequestResponseId { pub(crate) fn new(id: u8) -> Self { Self { id } } } -impl From for LocalRequestId { +impl From for LocalRequestResponseId { fn from(id: u16) -> Self { Self { id: id as u8 } } } -impl Into for LocalRequestId { +impl Into for LocalRequestResponseId { fn into(self) -> u16 { self.id as u16 } } -impl Serde for LocalRequestId { +impl Serde for LocalRequestResponseId { fn ser(&self, writer: &mut dyn BitWrite) { self.id.ser(writer) } diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index cb63f19cf..3e11da7a1 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -17,6 +17,7 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, unordered_unreliable_receiver::UnorderedUnreliableReceiver, }, senders::{ + request_sender::LocalRequestResponseId, channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, reliable_message_sender::ReliableMessageSender, sequenced_unreliable_sender::SequencedUnreliableSender, @@ -28,7 +29,6 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, remote::entity_waitlist::EntityWaitlist, }}; -use crate::messages::channels::senders::request_sender::LocalRequestId; /// Handles incoming/outgoing messages, tracks the delivery status of Messages /// so that guaranteed Messages can be re-transmitted to the remote host @@ -333,7 +333,7 @@ impl MessageManager { /// Retrieve all requests from the channel buffers pub fn receive_requests( &mut self, - ) -> Vec<(ChannelKind, Vec<(MessageKind, LocalRequestId, MessageContainer)>)> { + ) -> Vec<(ChannelKind, Vec<(MessageKind, LocalRequestResponseId, MessageContainer)>)> { let mut output = Vec::new(); for (channel_kind, channel) in &mut self.channel_receivers { let requests = channel.receive_requests(); diff --git a/shared/src/protocol.rs b/shared/src/protocol.rs index 6f9f40731..1fdad59ee 100644 --- a/shared/src/protocol.rs +++ b/shared/src/protocol.rs @@ -12,7 +12,7 @@ use crate::{connection::compression_config::CompressionConfig, messages::{ fragment::FragmentedMessage, message::Message, message_kinds::MessageKinds, -}, world::component::{component_kinds::ComponentKinds, replicate::Replicate}, EntityEventMessage, ReliableSettings, Request, RequestMessage}; +}, world::component::{component_kinds::ComponentKinds, replicate::Replicate}, EntityEventMessage, ReliableSettings, Request, RequestOrResponse}; // Protocol Plugin pub trait ProtocolPlugin { @@ -39,7 +39,7 @@ impl Default for Protocol { fn default() -> Self { let mut message_kinds = MessageKinds::new(); message_kinds.add_message::(); - message_kinds.add_message::(); + message_kinds.add_message::(); message_kinds.add_message::(); let mut channel_kinds = ChannelKinds::new(); From be76f0e5d1b095a7a374584714f4e248e7a575ef Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 5 Feb 2024 22:25:22 -0600 Subject: [PATCH 25/99] in progress.. --- adapters/bevy/client/src/events.rs | 4 +- adapters/bevy/server/src/events.rs | 4 +- client/src/client.rs | 43 +++---- client/src/connection/connection.rs | 41 ++++--- client/src/lib.rs | 2 +- client/src/request.rs | 8 +- .../bevy/shared/src/messages/basic_request.rs | 4 +- server/src/connection/connection.rs | 6 +- server/src/events.rs | 2 +- server/src/lib.rs | 2 +- server/src/request.rs | 8 +- server/src/server.rs | 4 +- shared/src/lib.rs | 7 +- .../channels/receivers/channel_receiver.rs | 5 +- .../receivers/reliable_message_receiver.rs | 47 ++++--- .../sequenced_unreliable_receiver.rs | 7 +- .../unordered_unreliable_receiver.rs | 7 +- .../channels/senders/channel_sender.rs | 3 +- .../senders/reliable_message_sender.rs | 5 +- .../channels/senders/request_sender.rs | 116 +++++++++++++----- .../senders/sequenced_unreliable_sender.rs | 3 +- .../senders/unordered_unreliable_sender.rs | 3 +- shared/src/messages/message_container.rs | 2 +- shared/src/messages/message_manager.rs | 16 +-- shared/src/messages/request.rs | 34 +++-- shared/src/types.rs | 2 - 26 files changed, 239 insertions(+), 146 deletions(-) diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 8d36a00cf..3875b52cb 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -2,7 +2,7 @@ use std::{any::Any, collections::HashMap, marker::PhantomData}; use bevy_ecs::{entity::Entity, prelude::Event}; -use naia_client::{shared::GlobalResponseId, Events, NaiaClientError}; +use naia_client::{shared::GlobalRequestResponseId, Events, NaiaClientError}; use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; @@ -106,7 +106,7 @@ impl MessageEvents { // RequestEvents #[derive(Event)] pub struct RequestEvents { - inner: HashMap>>, + inner: HashMap>>, phantom_t: PhantomData, } diff --git a/adapters/bevy/server/src/events.rs b/adapters/bevy/server/src/events.rs index f9e63598a..79a578646 100644 --- a/adapters/bevy/server/src/events.rs +++ b/adapters/bevy/server/src/events.rs @@ -3,7 +3,7 @@ use std::{any::Any, collections::HashMap}; use bevy_ecs::{entity::Entity, prelude::Event}; use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; -use naia_server::{shared::GlobalResponseId, Events, NaiaServerError, User, UserKey}; +use naia_server::{shared::GlobalRequestResponseId, Events, NaiaServerError, User, UserKey}; // ConnectEvent #[derive(Event)] @@ -94,7 +94,7 @@ fn convert_messages( // RequestEvents #[derive(Event)] pub struct RequestEvents { - inner: HashMap>>, + inner: HashMap>>, } impl From<&mut Events> for RequestEvents { diff --git a/client/src/client.rs b/client/src/client.rs index ac9fee953..29713ff95 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -2,7 +2,7 @@ use std::{any::Any, collections::VecDeque, hash::Hash, net::SocketAddr}; use log::{info, warn}; -use naia_shared::{BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, GlobalRequestId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; +use naia_shared::{BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; use super::{client_config::ClientConfig, error::NaiaClientError, events::Events}; use crate::{ @@ -35,9 +35,6 @@ pub struct Client { waitlist_messages: VecDeque<(ChannelKind, Box)>, // World global_world_manager: GlobalWorldManager, - // Request/Response - global_request_manager: GlobalRequestManager, - global_response_manager: GlobalResponseManager, // Events incoming_events: Events, // Hacky @@ -73,9 +70,6 @@ impl Client { waitlist_messages: VecDeque::new(), // World global_world_manager: GlobalWorldManager::new(), - // Requests - global_request_manager: GlobalRequestManager::new(), - global_response_manager: GlobalResponseManager::new(), // Events incoming_events: Events::new(), // Hacky @@ -204,7 +198,6 @@ impl Client { // receive packets, process into events response_events = Some(connection.process_packets( &mut self.global_world_manager, - &mut self.global_response_manager, &self.protocol, &mut world, &mut self.incoming_events, @@ -328,8 +321,6 @@ impl Client { std::panic!("Requests can only be sent over Bidirectional, Reliable Channels"); } - let request_id = self.global_request_manager.create_request_id(channel_kind); - let Some(connection) = &mut self.server_connection else { warn!("currently not connected to server"); return None; @@ -339,6 +330,7 @@ impl Client { &mut connection.base.local_world_manager, ); + let request_id = connection.global_request_manager.create_request_id(channel_kind); let message = MessageContainer::from_write(request_box, &mut converter); connection.base.message_manager.send_request( &self.protocol.message_kinds, @@ -354,49 +346,52 @@ impl Client { /// Sends a Response for a given Request. Returns whether or not was successful. pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { - let request_id = response_key.request_id(); - let Some(channel_kind) = self.global_request_manager.destroy_request_id(&request_id) else { - return false; - }; + let response_id = &response_key.response_id(); let cloned_response = S::clone_box(response); - self.send_response_inner(&channel_kind, request_id, cloned_response) + self.send_response_inner(response_id, cloned_response) } // returns whether was successful fn send_response_inner( &mut self, - channel_kind: &ChannelKind, - request_id: u64, + response_id: &GlobalResponseId, response_box: Box, ) -> bool { let Some(connection) = &mut self.server_connection else { return false; }; + let Some((channel_kind, message_kind, local_response_id)) = connection.global_response_manager.destroy_response_id(response_id) else { + return false; + }; let mut converter = EntityConverterMut::new( &self.global_world_manager, &mut connection.base.local_world_manager, ); - let message = MessageContainer::from_write(response_box, &mut converter); + + let response = MessageContainer::from_write(response_box, &mut converter); connection.base.message_manager.send_response( &self.protocol.message_kinds, &mut converter, - channel_kind, - request_id, - message, + &channel_kind, + local_response_id, + response, ); return true; } pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { - let response_id = response_key.response_id(); - let Some(container) = self.global_response_manager.destroy_response_id(&response_id) else { + let Some(connection) = &mut self.server_connection else { + return None; + }; + let request_id = response_key.request_id(); + let Some(container) = connection.global_request_manager.destroy_request_id(&request_id) else { return None; }; let response: S = Box::::downcast::(container.to_boxed_any()) .ok() - .map(|boxed_m| *boxed_m) + .map(|boxed_s| *boxed_s) .unwrap(); return Some(response); } diff --git a/client/src/connection/connection.rs b/client/src/connection/connection.rs index ad2b311e3..350ad99d9 100644 --- a/client/src/connection/connection.rs +++ b/client/src/connection/connection.rs @@ -2,12 +2,7 @@ use std::{any::Any, hash::Hash}; use log::warn; -use naia_shared::{ - BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, - ConnectionConfig, EntityEventMessage, EntityEventMessageAction, EntityResponseEvent, HostType, - HostWorldEvents, Instant, OwnedBitReader, PacketType, Protocol, Serde, SerdeErr, - StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType, -}; +use naia_shared::{BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, EntityEventMessage, EntityEventMessageAction, EntityResponseEvent, HostType, HostWorldEvents, Instant, LocalRequestOrResponseId, OwnedBitReader, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; use crate::{ request::GlobalResponseManager, @@ -18,6 +13,7 @@ use crate::{ events::Events, world::global_world_manager::GlobalWorldManager, }; +use crate::request::GlobalRequestManager; pub struct Connection { pub base: BaseConnection, @@ -26,6 +22,9 @@ pub struct Connection { /// Small buffer when receiving updates (entity actions, entity updates) from the server /// to make sure we receive them in order jitter_buffer: TickQueue, + // Request/Response + pub global_request_manager: GlobalRequestManager, + pub global_response_manager: GlobalResponseManager, } impl Connection { @@ -37,7 +36,7 @@ impl Connection { ) -> Self { let tick_buffer = TickBufferSender::new(channel_kinds); - let mut connection = Connection { + let mut connection = Self { base: BaseConnection::new( &None, HostType::Client, @@ -49,6 +48,8 @@ impl Connection { time_manager, tick_buffer, jitter_buffer: TickQueue::new(), + global_request_manager: GlobalRequestManager::new(), + global_response_manager: GlobalResponseManager::new(), }; let existing_entities = global_world_manager.entities(); @@ -109,7 +110,6 @@ impl Connection { pub fn process_packets>( &mut self, global_world_manager: &mut GlobalWorldManager, - global_response_manager: &mut GlobalResponseManager, protocol: &Protocol, world: &mut W, incoming_events: &mut Events, @@ -156,12 +156,25 @@ impl Connection { } } - // Receive Request Events - let requests = self.base.message_manager.receive_requests(); - for (channel_kind, requests) in requests { - for (message_kind, local_response_id, request) in requests { - let global_response_id = global_response_manager.create_response_id(&channel_kind, &message_kind, &local_response_id); - incoming_events.push_request(&channel_kind, global_response_id, request); + // Receive Request or Response Events + let requests_or_responses = self.base.message_manager.receive_requests_or_responses(); + for (channel_kind, requests_or_responses) in requests_or_responses { + for (message_kind, local_id, request_or_response) in requests_or_responses { + match local_id { + LocalRequestOrResponseId::Request(local_request_id) => { + // we have received an incoming request, need to generate a response id for it + let request = request_or_response; + let local_response_id = local_request_id.receive_from_remote(); + let global_response_id = self.global_response_manager.create_response_id(&channel_kind, &message_kind, &local_response_id); + incoming_events.push_request(&channel_kind, global_response_id, request); + } + LocalRequestOrResponseId::Response(local_response_id) => { + // we have received an incoming response, need to match it to the original request + let response = request_or_response; + let local_request_id = local_response_id.receive_from_remote(); + todo!(); + } + } } } diff --git a/client/src/lib.rs b/client/src/lib.rs index 83a9a8faf..a2876f2cc 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -17,7 +17,7 @@ pub mod transport; pub mod shared { pub use naia_shared::{ default_channels, sequence_greater_than, Instant, Message, Protocol, Random, SocketConfig, - Tick, GlobalResponseId, + Tick, GlobalRequestId, GlobalResponseId, }; } pub mod internal { diff --git a/client/src/request.rs b/client/src/request.rs index 7d951c070..575f91771 100644 --- a/client/src/request.rs +++ b/client/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestResponseId, MessageContainer, MessageKind}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestOrResponseId, LocalResponseId, MessageContainer, MessageKind}; // GlobalRequestManager pub struct GlobalRequestManager { @@ -16,7 +16,7 @@ impl GlobalRequestManager { todo!() } - pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option { + pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option { todo!() } } @@ -33,11 +33,11 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_req_res_id: &LocalRequestResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_response_id: &LocalResponseId) -> GlobalResponseId { todo!() } - pub(crate) fn destroy_response_id(&self, response_id: &GlobalResponseId) -> Option { + pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option<(ChannelKind, MessageKind, LocalResponseId)> { todo!() } } \ No newline at end of file diff --git a/demos/bevy/shared/src/messages/basic_request.rs b/demos/bevy/shared/src/messages/basic_request.rs index 4b686cc48..8b5e411ea 100644 --- a/demos/bevy/shared/src/messages/basic_request.rs +++ b/demos/bevy/shared/src/messages/basic_request.rs @@ -20,7 +20,9 @@ pub struct BasicResponse { pub contents: String, } -impl Response for BasicResponse {} +impl Response for BasicResponse { + type Request = BasicRequest; +} impl BasicResponse { pub fn new(contents: String) -> Self { diff --git a/server/src/connection/connection.rs b/server/src/connection/connection.rs index 7a2116b50..e590d9088 100644 --- a/server/src/connection/connection.rs +++ b/server/src/connection/connection.rs @@ -137,10 +137,10 @@ impl Connection { } // Receive Request Events - let requests = self.base.message_manager.receive_requests(); + let requests = self.base.message_manager.receive_requests_or_responses(); for (channel_kind, requests) in requests { - for (message_kind, local_request_id, request) in requests { - let global_response_id = global_response_manager.create_response_id(&channel_kind, &message_kind, &local_request_id); + for (message_kind, local_response_id, request) in requests { + let global_response_id = global_response_manager.create_response_id(&channel_kind, &message_kind, local_response_id); incoming_events.push_request(&self.user_key, &channel_kind, global_response_id, request); } } diff --git a/server/src/events.rs b/server/src/events.rs index ac3ce0ed2..227627aac 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -2,7 +2,7 @@ use std::{any::Any, collections::HashMap, marker::PhantomData, mem, vec::IntoIte use log::warn; -use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, GlobalResponseId, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, GlobalResponseId, EntityResponseEvent, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; use super::user::{User, UserKey}; use crate::NaiaServerError; diff --git a/server/src/lib.rs b/server/src/lib.rs index b6422095c..26d7d5f8c 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -18,7 +18,7 @@ pub mod shared { pub use naia_shared::{ default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, Random, Serde, SerdeErr, SignedInteger, SignedVariableInteger, SocketConfig, - UnsignedInteger, UnsignedVariableInteger, GlobalResponseId, + UnsignedInteger, UnsignedVariableInteger, }; } pub mod internal { diff --git a/server/src/request.rs b/server/src/request.rs index 3ecf95ace..50096b4ee 100644 --- a/server/src/request.rs +++ b/server/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestResponseId, MessageContainer, MessageKind}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestOrResponseId, LocalResponseId, MessageContainer, MessageKind}; use crate::UserKey; @@ -18,7 +18,7 @@ impl GlobalRequestManager { todo!() } - pub(crate) fn destroy_request_id(&self, request_id: &GlobalRequestId) -> Option<(UserKey, ChannelKind)> { + pub(crate) fn destroy_request_id(&self, global_request_id: &GlobalRequestId) -> Option<(UserKey, ChannelKind)> { todo!() } } @@ -35,11 +35,11 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_req_res_id: &LocalRequestResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_response_id: LocalResponseId) -> GlobalResponseId { todo!() } - pub(crate) fn destroy_response_id(&self, response_id: &GlobalResponseId) -> Option { + pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option { todo!() } } \ No newline at end of file diff --git a/server/src/server.rs b/server/src/server.rs index 53da82dc8..d09fa1aba 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -342,7 +342,7 @@ impl Server { /// Sends a Response for a given Request. Returns whether or not was successful. pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { - let request_id = response_key.request_id(); + let request_id = response_key.response_id(); let Some((user_key, channel_kind)) = self.global_request_manager.destroy_request_id(&request_id) else { return false; }; @@ -382,7 +382,7 @@ impl Server { } pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { - let response_id = response_key.response_id(); + let response_id = response_key.request_id(); let Some(container) = self.global_response_manager.destroy_response_id(&response_id) else { return None; }; diff --git a/shared/src/lib.rs b/shared/src/lib.rs index d5d737da8..fdce250d6 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -72,6 +72,7 @@ pub use messages::{ senders::{ channel_sender::{ChannelSender, MessageChannelSender}, reliable_sender::ReliableSender, + request_sender::LocalResponseId, }, system_channel::SystemChannel, }, @@ -80,7 +81,7 @@ pub use messages::{ message_kinds::{MessageKind, MessageKinds}, message_manager::MessageManager, named::Named, - request::{Request, Response, ResponseReceiveKey, ResponseSendKey}, + request::{Request, Response, ResponseReceiveKey, ResponseSendKey, GlobalResponseId, GlobalRequestId}, }; pub use world::{ component::{ @@ -136,7 +137,7 @@ pub use world::{ pub use bigmap::{BigMap, BigMapKey}; pub use game_time::{GAME_TIME_LIMIT, GameDuration, GameInstant}; pub use key_generator::KeyGenerator; -pub use messages::channels::senders::request_sender::{LocalRequestResponseId, RequestOrResponse}; +pub use messages::channels::senders::request_sender::{LocalRequestOrResponseId, RequestOrResponse}; pub use protocol::{Protocol, ProtocolPlugin}; -pub use types::{GlobalRequestId, GlobalResponseId, HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick}; +pub use types::{HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick}; pub use wrapping_number::{sequence_greater_than, sequence_less_than, wrapping_diff}; diff --git a/shared/src/messages/channels/receivers/channel_receiver.rs b/shared/src/messages/channels/receivers/channel_receiver.rs index a53965e47..88aa31752 100644 --- a/shared/src/messages/channels/receivers/channel_receiver.rs +++ b/shared/src/messages/channels/receivers/channel_receiver.rs @@ -1,6 +1,7 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, MessageKind, messages::{channels::senders::request_sender::LocalRequestResponseId, message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; +use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageKind, messages::{channels::senders::request_sender::LocalRequestOrResponseId, message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; +use crate::messages::channels::senders::request_sender::LocalRequestId; pub trait ChannelReceiver

: Send + Sync { /// Read messages from an internal buffer and return their content @@ -22,5 +23,5 @@ pub trait MessageChannelReceiver: ChannelReceiver { reader: &mut BitReader, ) -> Result<(), SerdeErr>; - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)>; + fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>); } diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index dbeea2dfc..b184d14ce 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -1,14 +1,15 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ +use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, MessageKind, messages::{ channels::{receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, fragment_receiver::FragmentReceiver, indexed_message_reader::IndexedMessageReader, reliable_receiver::ReliableReceiver, - }, senders::request_sender::LocalRequestResponseId}, + }, senders::request_sender::LocalRequestOrResponseId}, message_kinds::MessageKinds, }, RequestOrResponse, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; +use crate::messages::channels::senders::request_sender::LocalRequestId; // Receiver Arranger Trait pub trait ReceiverArranger: Send + Sync { @@ -27,7 +28,8 @@ pub struct ReliableMessageReceiver { fragment_receiver: FragmentReceiver, waitlist_store: WaitlistStore<(MessageIndex, MessageContainer)>, current_index: MessageIndex, - incoming_requests: Vec<(MessageKind, LocalRequestResponseId, MessageContainer)>, + incoming_requests: Vec<(MessageKind, LocalResponseId, MessageContainer)>, + incoming_responses: Vec<(LocalRequestId, MessageContainer)>, } impl ReliableMessageReceiver { @@ -40,6 +42,7 @@ impl ReliableMessageReceiver { waitlist_store: WaitlistStore::new(), current_index: 0, incoming_requests: Vec::new(), + incoming_responses: Vec::new(), } } @@ -104,24 +107,36 @@ impl ReliableMessageReceiver { converter: &dyn LocalEntityAndGlobalEntityConverter, message_container: MessageContainer ) { - // look at message, see if it's a request - if message_container.is_request() { + // look at message, see if it's a request or response + if message_container.is_request_or_response() { // it is! cast it - let request_container = message_container + let request_or_response_container = message_container .to_boxed_any() .downcast::() .unwrap(); - let (local_request_id, request_bytes) = request_container.to_id_and_bytes(); + let (local_id, request_bytes) = request_or_response_container.to_id_and_bytes(); let mut reader = BitReader::new(&request_bytes); - let request_result = message_kinds.read(&mut reader, converter); - if request_result.is_err() { + let request_or_response_result = message_kinds.read(&mut reader, converter); + if request_or_response_result.is_err() { // TODO: bubble up error instead of panicking here - panic!("Cannot read request message!"); + panic!("Cannot read request or response message!"); + } + let request_or_response = request_or_response_result.unwrap(); + + // add it to incoming requests or responses + match local_id { + LocalRequestOrResponseId::Request(local_request_id) => { + let request = request_or_response; + let local_response_id = local_request_id.receive_from_remote(); + self.incoming_requests + .push((request_or_response.kind(), local_response_id, request)); + } + LocalRequestOrResponseId::Response(local_response_id) => { + let response = request_or_response; + let local_request_id = local_response_id.receive_from_remote(); + self.incoming_responses.push((local_request_id, response)); + } } - let request = request_result.unwrap(); - // add it to incoming requests - self.incoming_requests - .push((request.kind(), local_request_id, request)); } else { // it's not a request, just add it to incoming messages self.incoming_messages.push(message_container); @@ -166,7 +181,7 @@ impl MessageChannelReceiver for ReliableMessageReceiver Ok(()) } - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)> { - std::mem::take(&mut self.incoming_requests) + fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { + (std::mem::take(&mut self.incoming_requests), std::mem::take(&mut self.incoming_responses)) } } diff --git a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs index efb6d674c..855f18a94 100644 --- a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs @@ -2,13 +2,14 @@ use std::mem; use naia_serde::{BitReader, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ +use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, MessageKind, messages::{ channels::{receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, indexed_message_reader::IndexedMessageReader, - }, senders::request_sender::LocalRequestResponseId}, + }, senders::request_sender::LocalRequestOrResponseId}, message_kinds::MessageKinds, }, sequence_greater_than, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; +use crate::messages::channels::senders::request_sender::LocalRequestId; pub struct SequencedUnreliableReceiver { newest_received_message_index: Option, @@ -91,7 +92,7 @@ impl MessageChannelReceiver for SequencedUnreliableReceiver { Ok(()) } - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)> { + fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { panic!("SequencedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs index 5fa5d381c..aa05a7a9d 100644 --- a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs @@ -2,10 +2,11 @@ use std::{collections::VecDeque, mem}; use naia_serde::{BitReader, Serde, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, MessageContainer, MessageKind, messages::{ - channels::{receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, senders::request_sender::LocalRequestResponseId}, +use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, MessageKind, messages::{ + channels::{receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, senders::request_sender::LocalRequestOrResponseId}, message_kinds::MessageKinds, }, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; +use crate::messages::channels::senders::request_sender::LocalRequestId; pub struct UnorderedUnreliableReceiver { incoming_messages: VecDeque, @@ -79,7 +80,7 @@ impl MessageChannelReceiver for UnorderedUnreliableReceiver { Ok(()) } - fn receive_requests(&mut self) -> Vec<(MessageKind, LocalRequestResponseId, MessageContainer)> { + fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { panic!("UnorderedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/senders/channel_sender.rs b/shared/src/messages/channels/senders/channel_sender.rs index b3b55657d..d128aaaaf 100644 --- a/shared/src/messages/channels/senders/channel_sender.rs +++ b/shared/src/messages/channels/senders/channel_sender.rs @@ -1,7 +1,8 @@ use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId}; +use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut}; +use crate::messages::request::GlobalRequestId; pub trait ChannelSender

: Send + Sync { /// Queues a Message to be transmitted to the remote host into an internal buffer diff --git a/shared/src/messages/channels/senders/reliable_message_sender.rs b/shared/src/messages/channels/senders/reliable_message_sender.rs index 37d0de070..76ed9174c 100644 --- a/shared/src/messages/channels/senders/reliable_message_sender.rs +++ b/shared/src/messages/channels/senders/reliable_message_sender.rs @@ -2,7 +2,7 @@ use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverterMut, messages::{ +use crate::{LocalEntityAndGlobalEntityConverterMut, messages::{ channels::senders::{ channel_sender::{ChannelSender, MessageChannelSender}, indexed_message_writer::IndexedMessageWriter, @@ -11,6 +11,7 @@ use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverterMut, messages::{ message_kinds::MessageKinds, }, ReliableSender, types::MessageIndex}; use crate::messages::channels::senders::request_sender::RequestSender; +use crate::messages::request::GlobalRequestId; // Sender pub struct ReliableMessageSender { @@ -69,7 +70,7 @@ impl MessageChannelSender for ReliableMessageSender { global_request_id: GlobalRequestId, request: MessageContainer ) { - let processed_request = self.request_sender.process_request( + let processed_request = self.request_sender.process_outgoing_request( message_kinds, converter, global_request_id, diff --git a/shared/src/messages/channels/senders/request_sender.rs b/shared/src/messages/channels/senders/request_sender.rs index a33bd2c59..fd1ce935f 100644 --- a/shared/src/messages/channels/senders/request_sender.rs +++ b/shared/src/messages/channels/senders/request_sender.rs @@ -1,9 +1,10 @@ use std::{time::Duration, collections::HashMap}; use naia_derive::MessageRequest; -use naia_serde::{BitReader, BitWrite, BitWriter, Serde, SerdeErr}; +use naia_serde::{BitWriter, SerdeInternal}; -use crate::{types::GlobalRequestId, KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKind, MessageKinds}; +use crate::{KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKind, MessageKinds}; +use crate::messages::request::GlobalRequestId; pub struct RequestSender { channels: HashMap, @@ -16,25 +17,25 @@ impl RequestSender { } } - pub(crate) fn process_request( + pub(crate) fn process_outgoing_request( &mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, global_request_id: GlobalRequestId, request: MessageContainer ) -> MessageContainer { - let key = request.kind(); - if !self.channels.contains_key(&key) { - self.channels.insert(key.clone(), RequestSenderChannel::new()); + let message_kind = request.kind(); + if !self.channels.contains_key(&message_kind) { + self.channels.insert(message_kind.clone(), RequestSenderChannel::new()); } - let channel = self.channels.get_mut(&key).unwrap(); - channel.process_request(message_kinds, converter, global_request_id, request) + let channel = self.channels.get_mut(&message_kind).unwrap(); + channel.process_outgoing_request(message_kinds, converter, global_request_id, request) } } pub struct RequestSenderChannel { - local_key_generator: KeyGenerator, - local_to_global_ids: HashMap, + local_key_generator: KeyGenerator, + local_to_global_ids: HashMap, } impl RequestSenderChannel { @@ -45,7 +46,7 @@ impl RequestSenderChannel { } } - pub(crate) fn process_request( + pub(crate) fn process_outgoing_request( &mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, @@ -53,70 +54,117 @@ impl RequestSenderChannel { request: MessageContainer ) -> MessageContainer { - let request_key = self.local_key_generator.generate(); - self.local_to_global_ids.insert(request_key, global_request_id); + let local_id = self.local_key_generator.generate(); + self.local_to_global_ids.insert(local_id, global_request_id); let mut writer = BitWriter::with_max_capacity(); request.write(message_kinds, &mut writer, converter); let request_bytes = writer.to_bytes(); - let request_message = RequestOrResponse::new(request_key, request_bytes); + let request_message = RequestOrResponse::request(local_id, request_bytes); MessageContainer::from_write(Box::new(request_message), converter) } } #[derive(MessageRequest)] pub struct RequestOrResponse { - id: LocalRequestResponseId, + id: LocalRequestOrResponseId, bytes: Box<[u8]>, } impl RequestOrResponse { - pub fn new(request_id: LocalRequestResponseId, bytes: Box<[u8]>) -> Self { + pub fn request(id: LocalRequestId, bytes: Box<[u8]>) -> Self { Self { - id: request_id, + id: id.to_req_res_id(), bytes, } } - pub(crate) fn to_id_and_bytes(self) -> (LocalRequestResponseId, Box<[u8]>) { + pub fn response(id: LocalResponseId, bytes: Box<[u8]>) -> Self { + Self { + id: id.to_req_res_id(), + bytes, + } + } + + pub(crate) fn to_id_and_bytes(self) -> (LocalRequestOrResponseId, Box<[u8]>) { (self.id, self.bytes) } } -#[derive(Clone, Copy, Eq, Hash, PartialEq)] -pub struct LocalRequestResponseId { +#[derive(Clone, PartialEq, Eq, SerdeInternal)] +pub enum LocalRequestOrResponseId { + Request(LocalRequestId), + Response(LocalResponseId), +} + +impl LocalRequestOrResponseId { + pub fn is_request(&self) -> bool { + match self { + LocalRequestOrResponseId::Request(_) => true, + LocalRequestOrResponseId::Response(_) => false, + } + } + + pub fn is_response(&self) -> bool { + match self { + LocalRequestOrResponseId::Request(_) => false, + LocalRequestOrResponseId::Response(_) => true, + } + } + + pub fn to_request_id(&self) -> LocalRequestId { + match self { + LocalRequestOrResponseId::Request(id) => *id, + LocalRequestOrResponseId::Response(_) => panic!("LocalRequestOrResponseId is a response"), + } + } + + pub fn to_response_id(&self) -> LocalResponseId { + match self { + LocalRequestOrResponseId::Request(_) => panic!("LocalRequestOrResponseId is a request"), + LocalRequestOrResponseId::Response(id) => *id, + } + } +} + +#[derive(Clone, Copy, Eq, Hash, PartialEq, SerdeInternal)] +pub struct LocalRequestId { id: u8, } -impl LocalRequestResponseId { - pub(crate) fn new(id: u8) -> Self { - Self { id } +impl LocalRequestId { + pub fn to_req_res_id(&self) -> LocalRequestOrResponseId { + LocalRequestOrResponseId::Request(*self) + } + + pub fn receive_from_remote(&self) -> LocalResponseId { + LocalResponseId { id: self.id } } } -impl From for LocalRequestResponseId { +impl From for LocalRequestId { fn from(id: u16) -> Self { Self { id: id as u8 } } } -impl Into for LocalRequestResponseId { +impl Into for LocalRequestId { fn into(self) -> u16 { self.id as u16 } } -impl Serde for LocalRequestResponseId { - fn ser(&self, writer: &mut dyn BitWrite) { - self.id.ser(writer) - } +#[derive(Clone, Copy, Eq, Hash, PartialEq, SerdeInternal)] +pub struct LocalResponseId { + id: u8, +} - fn de(reader: &mut BitReader) -> Result { - let id = u8::de(reader)?; - Ok(Self { id }) +impl LocalResponseId { + pub fn to_req_res_id(&self) -> LocalRequestOrResponseId { + LocalRequestOrResponseId::Response(*self) } - fn bit_length(&self) -> u32 { - self.id.bit_length() + pub fn receive_from_remote(&self) -> LocalRequestId { + LocalRequestId { id: self.id } } } \ No newline at end of file diff --git a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs index ca7495724..a011f3dad 100644 --- a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs @@ -10,7 +10,8 @@ use crate::{messages::{ }, message_container::MessageContainer, message_kinds::MessageKinds, -}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId}; +}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut}; +use crate::messages::request::GlobalRequestId; pub struct SequencedUnreliableSender { /// Buffer of the next messages to send along with their MessageKind diff --git a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs index 465fff4d8..2e4a5f9f9 100644 --- a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs @@ -7,7 +7,8 @@ use crate::{messages::{ channels::senders::channel_sender::{ChannelSender, MessageChannelSender}, message_container::MessageContainer, message_kinds::MessageKinds, -}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, GlobalRequestId}; +}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut}; +use crate::messages::request::GlobalRequestId; pub struct UnorderedUnreliableSender { outgoing_messages: VecDeque, diff --git a/shared/src/messages/message_container.rs b/shared/src/messages/message_container.rs index aecf5e0b9..e954ce91c 100644 --- a/shared/src/messages/message_container.rs +++ b/shared/src/messages/message_container.rs @@ -59,7 +59,7 @@ impl MessageContainer { return self.inner.is_fragment(); } - pub fn is_request(&self) -> bool { + pub fn is_request_or_response(&self) -> bool { return self.inner.is_request(); } diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index 3e11da7a1..537867d78 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -17,7 +17,7 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, unordered_unreliable_receiver::UnorderedUnreliableReceiver, }, senders::{ - request_sender::LocalRequestResponseId, + request_sender::LocalRequestOrResponseId, channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, reliable_message_sender::ReliableMessageSender, sequenced_unreliable_sender::SequencedUnreliableSender, @@ -25,10 +25,12 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, }, }, message_container::MessageContainer, -}, Protocol, types::{GlobalRequestId, HostType, MessageIndex, PacketIndex}, world::{ +}, Protocol, types::{HostType, MessageIndex, PacketIndex}, world::{ entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, remote::entity_waitlist::EntityWaitlist, }}; +use crate::messages::channels::senders::request_sender::LocalResponseId; +use crate::messages::request::GlobalRequestId; /// Handles incoming/outgoing messages, tracks the delivery status of Messages /// so that guaranteed Messages can be re-transmitted to the remote host @@ -208,7 +210,7 @@ impl MessageManager { message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, channel_kind: &ChannelKind, - global_request_id: GlobalRequestId, + local_response_id: LocalResponseId, response: MessageContainer ) { todo!() @@ -331,13 +333,13 @@ impl MessageManager { } /// Retrieve all requests from the channel buffers - pub fn receive_requests( + pub fn receive_requests_or_responses( &mut self, - ) -> Vec<(ChannelKind, Vec<(MessageKind, LocalRequestResponseId, MessageContainer)>)> { + ) -> Vec<(ChannelKind, Vec<(MessageKind, LocalRequestOrResponseId, MessageContainer)>)> { let mut output = Vec::new(); for (channel_kind, channel) in &mut self.channel_receivers { - let requests = channel.receive_requests(); - output.push((channel_kind.clone(), requests)); + let requests_or_responses = channel.receive_requests_and_responses(); + output.push((channel_kind.clone(), requests_or_responses)); } output } diff --git a/shared/src/messages/request.rs b/shared/src/messages/request.rs index a445a47b3..479354ffc 100644 --- a/shared/src/messages/request.rs +++ b/shared/src/messages/request.rs @@ -1,6 +1,6 @@ use std::marker::PhantomData; -use crate::{Message, types::GlobalRequestId}; +use crate::Message; // Request pub trait Request: Message { @@ -8,44 +8,56 @@ pub trait Request: Message { } // Response -pub trait Response: Message {} +pub trait Response: Message { + type Request: Request; +} // ResponseSendKey #[derive(Clone, Eq, PartialEq, Hash)] pub struct ResponseSendKey { - request_id: GlobalRequestId, + response_id: GlobalResponseId, phantom_s: PhantomData, } impl ResponseSendKey { - pub fn new(id: GlobalRequestId) -> Self { + pub fn new(id: GlobalResponseId) -> Self { Self { - request_id: id, + response_id: id, phantom_s: PhantomData, } } - pub fn request_id(&self) -> GlobalRequestId { - self.request_id + pub fn response_id(&self) -> GlobalResponseId { + self.response_id } } // ResponseReceiveKey #[derive(Clone, Eq, PartialEq, Hash)] pub struct ResponseReceiveKey { - response_id: GlobalRequestId, + request_id: GlobalRequestId, phantom_s: PhantomData, } impl ResponseReceiveKey { pub fn new(request_id: GlobalRequestId) -> Self { Self { - response_id: request_id, + request_id: request_id, phantom_s: PhantomData, } } - pub fn response_id(&self) -> GlobalRequestId { - self.response_id + pub fn request_id(&self) -> GlobalRequestId { + self.request_id } +} + +#[derive(Clone, Copy, Eq, Hash, PartialEq)] +pub struct GlobalRequestId { + id: u64, +} + +#[derive(Clone, Copy, Eq, Hash, PartialEq)] +pub struct GlobalResponseId { + id: u64, } \ No newline at end of file diff --git a/shared/src/types.rs b/shared/src/types.rs index 4ce557af2..7d116bc7b 100644 --- a/shared/src/types.rs +++ b/shared/src/types.rs @@ -2,8 +2,6 @@ pub type PacketIndex = u16; pub type Tick = u16; pub type MessageIndex = u16; pub type ShortMessageIndex = u8; -pub type GlobalRequestId = u64; -pub type GlobalResponseId = u64; #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] pub enum HostType { From 394a254ca9f4b3fed975693562641e8d08c99384 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 6 Feb 2024 14:02:27 -0600 Subject: [PATCH 26/99] finish implementing shared logic --- adapters/bevy/client/src/events.rs | 5 +- adapters/bevy/server/src/events.rs | 4 +- adapters/bevy/server/src/server.rs | 2 +- client/src/client.rs | 7 +-- client/src/connection/connection.rs | 32 ++++------- client/src/request.rs | 10 +++- server/src/connection/connection.rs | 16 ++++-- server/src/lib.rs | 2 +- server/src/request.rs | 12 ++-- server/src/server.rs | 39 +++++++------ .../channels/receivers/channel_receiver.rs | 4 +- .../receivers/reliable_message_receiver.rs | 8 +-- .../sequenced_unreliable_receiver.rs | 6 +- .../unordered_unreliable_receiver.rs | 6 +- .../channels/senders/channel_sender.rs | 11 +++- .../senders/reliable_message_sender.rs | 20 ++++++- .../channels/senders/request_sender.rs | 55 ++++++++----------- .../senders/sequenced_unreliable_sender.rs | 13 ++++- .../senders/unordered_unreliable_sender.rs | 13 ++++- shared/src/messages/message_manager.rs | 29 ++++++---- 20 files changed, 170 insertions(+), 124 deletions(-) diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 3875b52cb..53523e0fd 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -2,9 +2,10 @@ use std::{any::Any, collections::HashMap, marker::PhantomData}; use bevy_ecs::{entity::Entity, prelude::Event}; -use naia_client::{shared::GlobalRequestResponseId, Events, NaiaClientError}; +use naia_client::{Events, NaiaClientError}; use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_client::shared::GlobalResponseId; // ConnectEvent #[derive(Event)] @@ -106,7 +107,7 @@ impl MessageEvents { // RequestEvents #[derive(Event)] pub struct RequestEvents { - inner: HashMap>>, + inner: HashMap>>, phantom_t: PhantomData, } diff --git a/adapters/bevy/server/src/events.rs b/adapters/bevy/server/src/events.rs index 79a578646..f9e63598a 100644 --- a/adapters/bevy/server/src/events.rs +++ b/adapters/bevy/server/src/events.rs @@ -3,7 +3,7 @@ use std::{any::Any, collections::HashMap}; use bevy_ecs::{entity::Entity, prelude::Event}; use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; -use naia_server::{shared::GlobalRequestResponseId, Events, NaiaServerError, User, UserKey}; +use naia_server::{shared::GlobalResponseId, Events, NaiaServerError, User, UserKey}; // ConnectEvent #[derive(Event)] @@ -94,7 +94,7 @@ fn convert_messages( // RequestEvents #[derive(Event)] pub struct RequestEvents { - inner: HashMap>>, + inner: HashMap>>, } impl From<&mut Events> for RequestEvents { diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index a27d573bb..28dde5b73 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -72,7 +72,7 @@ impl<'w> Server<'w> { self.server.0.send_response(response_key, response) } - pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { + pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option<(UserKey, S)> { self.server.0.receive_response(response_key) } diff --git a/client/src/client.rs b/client/src/client.rs index 29713ff95..764089550 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -18,7 +18,6 @@ use crate::{ global_world_manager::GlobalWorldManager, }, ReplicationConfig, - request::{GlobalRequestManager, GlobalResponseManager}, }; /// Client can send/receive messages to/from a server, and has a pool of @@ -346,11 +345,11 @@ impl Client { /// Sends a Response for a given Request. Returns whether or not was successful. pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { - let response_id = &response_key.response_id(); + let response_id = response_key.response_id(); let cloned_response = S::clone_box(response); - self.send_response_inner(response_id, cloned_response) + self.send_response_inner(&response_id, cloned_response) } // returns whether was successful @@ -362,7 +361,7 @@ impl Client { let Some(connection) = &mut self.server_connection else { return false; }; - let Some((channel_kind, message_kind, local_response_id)) = connection.global_response_manager.destroy_response_id(response_id) else { + let Some((channel_kind, local_response_id)) = connection.global_response_manager.destroy_response_id(response_id) else { return false; }; let mut converter = EntityConverterMut::new( diff --git a/client/src/connection/connection.rs b/client/src/connection/connection.rs index 350ad99d9..f00d64dc8 100644 --- a/client/src/connection/connection.rs +++ b/client/src/connection/connection.rs @@ -2,7 +2,7 @@ use std::{any::Any, hash::Hash}; use log::warn; -use naia_shared::{BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, EntityEventMessage, EntityEventMessageAction, EntityResponseEvent, HostType, HostWorldEvents, Instant, LocalRequestOrResponseId, OwnedBitReader, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; +use naia_shared::{BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, EntityEventMessage, EntityEventMessageAction, EntityResponseEvent, HostType, HostWorldEvents, Instant, OwnedBitReader, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; use crate::{ request::GlobalResponseManager, @@ -156,27 +156,19 @@ impl Connection { } } - // Receive Request or Response Events - let requests_or_responses = self.base.message_manager.receive_requests_or_responses(); - for (channel_kind, requests_or_responses) in requests_or_responses { - for (message_kind, local_id, request_or_response) in requests_or_responses { - match local_id { - LocalRequestOrResponseId::Request(local_request_id) => { - // we have received an incoming request, need to generate a response id for it - let request = request_or_response; - let local_response_id = local_request_id.receive_from_remote(); - let global_response_id = self.global_response_manager.create_response_id(&channel_kind, &message_kind, &local_response_id); - incoming_events.push_request(&channel_kind, global_response_id, request); - } - LocalRequestOrResponseId::Response(local_response_id) => { - // we have received an incoming response, need to match it to the original request - let response = request_or_response; - let local_request_id = local_response_id.receive_from_remote(); - todo!(); - } - } + // Receive Request and Response Events + let (requests, responses) = self.base.message_manager.receive_requests_and_responses(); + // Requests + for (channel_kind, requests) in requests { + for (local_response_id, request) in requests { + let global_response_id = self.global_response_manager.create_response_id(&channel_kind, &local_response_id); + incoming_events.push_request(&channel_kind, global_response_id, request); } } + // Responses + for (global_request_id, response) in responses { + self.global_request_manager.receive_response(&global_request_id, response); + } // Receive World Events let remote_events = self.base.remote_world_reader.take_incoming_events(); diff --git a/client/src/request.rs b/client/src/request.rs index 575f91771..72e1ff89a 100644 --- a/client/src/request.rs +++ b/client/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestOrResponseId, LocalResponseId, MessageContainer, MessageKind}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer}; // GlobalRequestManager pub struct GlobalRequestManager { @@ -19,6 +19,10 @@ impl GlobalRequestManager { pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option { todo!() } + + pub(crate) fn receive_response(&mut self, request_id: &GlobalRequestId, response: MessageContainer) { + todo!() + } } // GlobalResponseManager @@ -33,11 +37,11 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_response_id: &LocalResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, local_response_id: &LocalResponseId) -> GlobalResponseId { todo!() } - pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option<(ChannelKind, MessageKind, LocalResponseId)> { + pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option<(ChannelKind, LocalResponseId)> { todo!() } } \ No newline at end of file diff --git a/server/src/connection/connection.rs b/server/src/connection/connection.rs index e590d9088..7df484adf 100644 --- a/server/src/connection/connection.rs +++ b/server/src/connection/connection.rs @@ -14,7 +14,7 @@ use crate::{ user::UserKey, world::global_world_manager::GlobalWorldManager, }; -use crate::request::GlobalResponseManager; +use crate::request::{GlobalRequestManager, GlobalResponseManager}; use super::ping_manager::PingManager; @@ -97,6 +97,7 @@ impl Connection { &mut self, protocol: &Protocol, global_world_manager: &mut GlobalWorldManager, + global_request_manager: &mut GlobalRequestManager, global_response_manager: &mut GlobalResponseManager, world: &mut W, incoming_events: &mut Events, @@ -136,14 +137,19 @@ impl Connection { } } - // Receive Request Events - let requests = self.base.message_manager.receive_requests_or_responses(); + // Receive Request and Response Events + let (requests, responses) = self.base.message_manager.receive_requests_and_responses(); + // Requests for (channel_kind, requests) in requests { - for (message_kind, local_response_id, request) in requests { - let global_response_id = global_response_manager.create_response_id(&channel_kind, &message_kind, local_response_id); + for (local_response_id, request) in requests { + let global_response_id = global_response_manager.create_response_id(&self.user_key, &channel_kind, &local_response_id); incoming_events.push_request(&self.user_key, &channel_kind, global_response_id, request); } } + // Responses + for (global_request_id, response) in responses { + global_request_manager.receive_response(&global_request_id, response); + } // Receive World Events if protocol.client_authoritative_entities { diff --git a/server/src/lib.rs b/server/src/lib.rs index 26d7d5f8c..b6422095c 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -18,7 +18,7 @@ pub mod shared { pub use naia_shared::{ default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, Random, Serde, SerdeErr, SignedInteger, SignedVariableInteger, SocketConfig, - UnsignedInteger, UnsignedVariableInteger, + UnsignedInteger, UnsignedVariableInteger, GlobalResponseId, }; } pub mod internal { diff --git a/server/src/request.rs b/server/src/request.rs index 50096b4ee..c36c3224d 100644 --- a/server/src/request.rs +++ b/server/src/request.rs @@ -1,4 +1,4 @@ -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalRequestOrResponseId, LocalResponseId, MessageContainer, MessageKind}; +use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer}; use crate::UserKey; @@ -18,7 +18,11 @@ impl GlobalRequestManager { todo!() } - pub(crate) fn destroy_request_id(&self, global_request_id: &GlobalRequestId) -> Option<(UserKey, ChannelKind)> { + pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option<(UserKey, MessageContainer)> { + todo!() + } + + pub(crate) fn receive_response(&mut self, request_id: &GlobalRequestId, response: MessageContainer) { todo!() } } @@ -35,11 +39,11 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, message_kind: &MessageKind, local_response_id: LocalResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id(&mut self, user_key: &UserKey, channel_kind: &ChannelKind, local_response_id: &LocalResponseId) -> GlobalResponseId { todo!() } - pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option { + pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option<(UserKey, ChannelKind, LocalResponseId)> { todo!() } } \ No newline at end of file diff --git a/server/src/server.rs b/server/src/server.rs index d09fa1aba..88b06a674 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -9,7 +9,7 @@ use std::{ use log::{info, warn}; -use naia_shared::{BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, GlobalEntity, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SerdeErr, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType}; +use naia_shared::{BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SerdeErr, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType}; use crate::{ connection::{ @@ -304,7 +304,7 @@ impl Server { channel_kind: &ChannelKind, // response_type_id: TypeId, request_box: Box, - ) -> Option { + ) -> Option { let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); @@ -342,25 +342,23 @@ impl Server { /// Sends a Response for a given Request. Returns whether or not was successful. pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { - let request_id = response_key.response_id(); - let Some((user_key, channel_kind)) = self.global_request_manager.destroy_request_id(&request_id) else { - return false; - }; + let response_id = response_key.response_id(); let cloned_response = S::clone_box(response); - self.send_response_inner(&user_key, &channel_kind, request_id, cloned_response) + self.send_response_inner(&response_id, cloned_response) } // returns whether was successful fn send_response_inner( &mut self, - user_key: &UserKey, - channel_kind: &ChannelKind, - request_id: u64, + response_id: &GlobalResponseId, response_box: Box, ) -> bool { - let Some(user) = self.users.get(user_key) else { + let Some((user_key, channel_kind, local_response_id)) = self.global_response_manager.destroy_response_id(&response_id) else { + return false; + }; + let Some(user) = self.users.get(&user_key) else { return false; }; let Some(connection) = self.user_connections.get_mut(&user.address) else { @@ -370,27 +368,27 @@ impl Server { &self.global_world_manager, &mut connection.base.local_world_manager, ); - let message = MessageContainer::from_write(response_box, &mut converter); + let response = MessageContainer::from_write(response_box, &mut converter); connection.base.message_manager.send_response( &self.protocol.message_kinds, &mut converter, - channel_kind, - request_id, - message, + &channel_kind, + local_response_id, + response, ); return true; } - pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { - let response_id = response_key.request_id(); - let Some(container) = self.global_response_manager.destroy_response_id(&response_id) else { + pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option<(UserKey, S)> { + let request_id = response_key.request_id(); + let Some((user_key, container)) = self.global_request_manager.destroy_request_id(&request_id) else { return None; }; let response: S = Box::::downcast::(container.to_boxed_any()) .ok() - .map(|boxed_m| *boxed_m) + .map(|boxed_s| *boxed_s) .unwrap(); - return Some(response); + return Some((user_key, response)); } // @@ -1804,6 +1802,7 @@ impl Server { connection.process_packets( &self.protocol, &mut self.global_world_manager, + &mut self.global_request_manager, &mut self.global_response_manager, world, &mut self.incoming_events, diff --git a/shared/src/messages/channels/receivers/channel_receiver.rs b/shared/src/messages/channels/receivers/channel_receiver.rs index 88aa31752..c233291cd 100644 --- a/shared/src/messages/channels/receivers/channel_receiver.rs +++ b/shared/src/messages/channels/receivers/channel_receiver.rs @@ -1,6 +1,6 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageKind, messages::{channels::senders::request_sender::LocalRequestOrResponseId, message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; +use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, messages::{message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; use crate::messages::channels::senders::request_sender::LocalRequestId; pub trait ChannelReceiver

: Send + Sync { @@ -23,5 +23,5 @@ pub trait MessageChannelReceiver: ChannelReceiver { reader: &mut BitReader, ) -> Result<(), SerdeErr>; - fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>); + fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>); } diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index b184d14ce..fcbd76c0e 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -1,6 +1,6 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, MessageKind, messages::{ +use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, messages::{ channels::{receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, fragment_receiver::FragmentReceiver, @@ -28,7 +28,7 @@ pub struct ReliableMessageReceiver { fragment_receiver: FragmentReceiver, waitlist_store: WaitlistStore<(MessageIndex, MessageContainer)>, current_index: MessageIndex, - incoming_requests: Vec<(MessageKind, LocalResponseId, MessageContainer)>, + incoming_requests: Vec<(LocalResponseId, MessageContainer)>, incoming_responses: Vec<(LocalRequestId, MessageContainer)>, } @@ -129,7 +129,7 @@ impl ReliableMessageReceiver { let request = request_or_response; let local_response_id = local_request_id.receive_from_remote(); self.incoming_requests - .push((request_or_response.kind(), local_response_id, request)); + .push((local_response_id, request)); } LocalRequestOrResponseId::Response(local_response_id) => { let response = request_or_response; @@ -181,7 +181,7 @@ impl MessageChannelReceiver for ReliableMessageReceiver Ok(()) } - fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { + fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { (std::mem::take(&mut self.incoming_requests), std::mem::take(&mut self.incoming_responses)) } } diff --git a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs index 855f18a94..cd674b46c 100644 --- a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs @@ -2,11 +2,11 @@ use std::mem; use naia_serde::{BitReader, SerdeErr}; -use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, MessageKind, messages::{ +use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, messages::{ channels::{receivers::{ channel_receiver::{ChannelReceiver, MessageChannelReceiver}, indexed_message_reader::IndexedMessageReader, - }, senders::request_sender::LocalRequestOrResponseId}, + }}, message_kinds::MessageKinds, }, sequence_greater_than, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; use crate::messages::channels::senders::request_sender::LocalRequestId; @@ -92,7 +92,7 @@ impl MessageChannelReceiver for SequencedUnreliableReceiver { Ok(()) } - fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { + fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { panic!("SequencedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs index aa05a7a9d..190b70f6b 100644 --- a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs @@ -2,8 +2,8 @@ use std::{collections::VecDeque, mem}; use naia_serde::{BitReader, Serde, SerdeErr}; -use crate::{GlobalRequestId, LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, MessageKind, messages::{ - channels::{receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, senders::request_sender::LocalRequestOrResponseId}, +use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, messages::{ + channels::{receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}}, message_kinds::MessageKinds, }, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; use crate::messages::channels::senders::request_sender::LocalRequestId; @@ -80,7 +80,7 @@ impl MessageChannelReceiver for UnorderedUnreliableReceiver { Ok(()) } - fn receive_requests_and_responses(&mut self) -> (Vec<(MessageKind, LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { + fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { panic!("UnorderedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/senders/channel_sender.rs b/shared/src/messages/channels/senders/channel_sender.rs index d128aaaaf..e8d35a850 100644 --- a/shared/src/messages/channels/senders/channel_sender.rs +++ b/shared/src/messages/channels/senders/channel_sender.rs @@ -1,7 +1,8 @@ use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut}; +use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, LocalResponseId}; +use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::messages::request::GlobalRequestId; pub trait ChannelSender

: Send + Sync { @@ -26,5 +27,11 @@ pub trait MessageChannelSender: ChannelSender { ) -> Option>; /// Queues a Request to be transmitted to the remote host into an internal buffer - fn send_request(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, global_request_id: GlobalRequestId, request: MessageContainer); + fn send_outgoing_request(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, global_request_id: GlobalRequestId, request: MessageContainer); + + /// Queues a Response to be transmitted to the remote host into an internal buffer + fn send_outgoing_response(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, local_response_id: LocalResponseId, response: MessageContainer); + + /// Request is finished, so clean up the local request id and return the global request id + fn process_incoming_response(&mut self, local_request_id: &LocalRequestId) -> Option; } diff --git a/shared/src/messages/channels/senders/reliable_message_sender.rs b/shared/src/messages/channels/senders/reliable_message_sender.rs index 76ed9174c..49b09af5d 100644 --- a/shared/src/messages/channels/senders/reliable_message_sender.rs +++ b/shared/src/messages/channels/senders/reliable_message_sender.rs @@ -2,7 +2,7 @@ use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{LocalEntityAndGlobalEntityConverterMut, messages::{ +use crate::{LocalEntityAndGlobalEntityConverterMut, LocalResponseId, messages::{ channels::senders::{ channel_sender::{ChannelSender, MessageChannelSender}, indexed_message_writer::IndexedMessageWriter, @@ -10,7 +10,7 @@ use crate::{LocalEntityAndGlobalEntityConverterMut, messages::{ message_container::MessageContainer, message_kinds::MessageKinds, }, ReliableSender, types::MessageIndex}; -use crate::messages::channels::senders::request_sender::RequestSender; +use crate::messages::channels::senders::request_sender::{LocalRequestId, RequestSender}; use crate::messages::request::GlobalRequestId; // Sender @@ -63,7 +63,7 @@ impl MessageChannelSender for ReliableMessageSender { ) } - fn send_request( + fn send_outgoing_request( &mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, @@ -78,4 +78,18 @@ impl MessageChannelSender for ReliableMessageSender { ); self.send_message(processed_request); } + + fn send_outgoing_response(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, local_response_id: LocalResponseId, response: MessageContainer) { + let processed_response = self.request_sender.process_outgoing_response( + message_kinds, + converter, + local_response_id, + response, + ); + self.send_message(processed_response); + } + + fn process_incoming_response(&mut self, local_request_id: &LocalRequestId) -> Option { + self.request_sender.process_incoming_response(local_request_id) + } } diff --git a/shared/src/messages/channels/senders/request_sender.rs b/shared/src/messages/channels/senders/request_sender.rs index fd1ce935f..ae56d881b 100644 --- a/shared/src/messages/channels/senders/request_sender.rs +++ b/shared/src/messages/channels/senders/request_sender.rs @@ -3,17 +3,19 @@ use std::{time::Duration, collections::HashMap}; use naia_derive::MessageRequest; use naia_serde::{BitWriter, SerdeInternal}; -use crate::{KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKind, MessageKinds}; +use crate::{KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKinds}; use crate::messages::request::GlobalRequestId; pub struct RequestSender { - channels: HashMap, + local_key_generator: KeyGenerator, + local_to_global_ids: HashMap, } impl RequestSender { pub fn new() -> Self { Self { - channels: HashMap::new(), + local_key_generator: KeyGenerator::new(Duration::from_secs(60)), + local_to_global_ids: HashMap::new(), } } @@ -24,44 +26,35 @@ impl RequestSender { global_request_id: GlobalRequestId, request: MessageContainer ) -> MessageContainer { - let message_kind = request.kind(); - if !self.channels.contains_key(&message_kind) { - self.channels.insert(message_kind.clone(), RequestSenderChannel::new()); - } - let channel = self.channels.get_mut(&message_kind).unwrap(); - channel.process_outgoing_request(message_kinds, converter, global_request_id, request) - } -} -pub struct RequestSenderChannel { - local_key_generator: KeyGenerator, - local_to_global_ids: HashMap, -} + let local_request_id = self.local_key_generator.generate(); + self.local_to_global_ids.insert(local_request_id, global_request_id); -impl RequestSenderChannel { - pub fn new() -> Self { - Self { - local_key_generator: KeyGenerator::new(Duration::from_secs(60)), - local_to_global_ids: HashMap::new(), - } + let mut writer = BitWriter::with_max_capacity(); + request.write(message_kinds, &mut writer, converter); + let request_bytes = writer.to_bytes(); + let request_message = RequestOrResponse::request(local_request_id, request_bytes); + MessageContainer::from_write(Box::new(request_message), converter) } - pub(crate) fn process_outgoing_request( + pub(crate) fn process_outgoing_response( &mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, - global_request_id: GlobalRequestId, - request: MessageContainer + local_response_id: LocalResponseId, + response: MessageContainer ) -> MessageContainer { - let local_id = self.local_key_generator.generate(); - self.local_to_global_ids.insert(local_id, global_request_id); - let mut writer = BitWriter::with_max_capacity(); - request.write(message_kinds, &mut writer, converter); - let request_bytes = writer.to_bytes(); - let request_message = RequestOrResponse::request(local_id, request_bytes); - MessageContainer::from_write(Box::new(request_message), converter) + response.write(message_kinds, &mut writer, converter); + let response_bytes = writer.to_bytes(); + let response_message = RequestOrResponse::response(local_response_id, response_bytes); + MessageContainer::from_write(Box::new(response_message), converter) + } + + pub(crate) fn process_incoming_response(&mut self, local_request_id: &LocalRequestId) -> Option { + self.local_key_generator.recycle_key(local_request_id); + self.local_to_global_ids.remove(local_request_id) } } diff --git a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs index a011f3dad..c2c8a04ae 100644 --- a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs @@ -10,7 +10,8 @@ use crate::{messages::{ }, message_container::MessageContainer, message_kinds::MessageKinds, -}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut}; +}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, LocalResponseId}; +use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::messages::request::GlobalRequestId; pub struct SequencedUnreliableSender { @@ -68,7 +69,15 @@ impl MessageChannelSender for SequencedUnreliableSender { ) } - fn send_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + fn send_outgoing_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + panic!("SequencedUnreliable channel does not support requests"); + } + + fn send_outgoing_response(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: LocalResponseId, _: MessageContainer) { + panic!("SequencedUnreliable channel does not support requests"); + } + + fn process_incoming_response(&mut self, _: &LocalRequestId) -> Option { panic!("SequencedUnreliable channel does not support requests"); } } diff --git a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs index 2e4a5f9f9..ee4a690fe 100644 --- a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs @@ -7,7 +7,8 @@ use crate::{messages::{ channels::senders::channel_sender::{ChannelSender, MessageChannelSender}, message_container::MessageContainer, message_kinds::MessageKinds, -}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut}; +}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, LocalResponseId}; +use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::messages::request::GlobalRequestId; pub struct UnorderedUnreliableSender { @@ -101,7 +102,15 @@ impl MessageChannelSender for UnorderedUnreliableSender { None } - fn send_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + fn send_outgoing_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + panic!("UnorderedUnreliable channel does not support requests"); + } + + fn process_incoming_response(&mut self, _: &LocalRequestId) -> Option { + panic!("UnorderedUnreliable channel does not support requests"); + } + + fn send_outgoing_response(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: LocalResponseId, _: MessageContainer) { panic!("UnorderedUnreliable channel does not support requests"); } } diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index 537867d78..f30536b02 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -3,7 +3,7 @@ use std::{collections::HashMap, hash::Hash}; use naia_serde::{BitReader, BitWrite, BitWriter, ConstBitLength, Serde, SerdeErr}; use naia_socket_shared::Instant; -use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKind, MessageKinds, messages::{ +use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, messages::{ channels::{ channel::ChannelMode, channel::ChannelSettings, @@ -17,7 +17,6 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, unordered_unreliable_receiver::UnorderedUnreliableReceiver, }, senders::{ - request_sender::LocalRequestOrResponseId, channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, reliable_message_sender::ReliableMessageSender, sequenced_unreliable_sender::SequencedUnreliableSender, @@ -202,7 +201,7 @@ impl MessageManager { let Some(channel) = self.channel_senders.get_mut(channel_kind) else { panic!("Channel not configured correctly! Cannot send message."); }; - channel.send_request(message_kinds, converter, global_request_id, request); + channel.send_outgoing_request(message_kinds, converter, global_request_id, request); } pub fn send_response( @@ -213,7 +212,10 @@ impl MessageManager { local_response_id: LocalResponseId, response: MessageContainer ) { - todo!() + let Some(channel) = self.channel_senders.get_mut(channel_kind) else { + panic!("Channel not configured correctly! Cannot send message."); + }; + channel.send_outgoing_response(message_kinds, converter, local_response_id, response); } pub fn collect_outgoing_messages(&mut self, now: &Instant, rtt_millis: &f32) { @@ -333,15 +335,22 @@ impl MessageManager { } /// Retrieve all requests from the channel buffers - pub fn receive_requests_or_responses( + pub fn receive_requests_and_responses( &mut self, - ) -> Vec<(ChannelKind, Vec<(MessageKind, LocalRequestOrResponseId, MessageContainer)>)> { - let mut output = Vec::new(); + ) -> (Vec<(ChannelKind, Vec<(LocalResponseId, MessageContainer)>)>, Vec<(GlobalRequestId, MessageContainer)>) { + let mut request_output = Vec::new(); + let mut response_output = Vec::new(); for (channel_kind, channel) in &mut self.channel_receivers { - let requests_or_responses = channel.receive_requests_and_responses(); - output.push((channel_kind.clone(), requests_or_responses)); + let (requests, responses) = channel.receive_requests_and_responses(); + request_output.push((channel_kind.clone(), requests)); + + let channel_sender = self.channel_senders.get_mut(channel_kind).unwrap(); + for (local_request_id, response) in responses { + let global_request_id = channel_sender.process_incoming_response(&local_request_id).unwrap(); + response_output.push((global_request_id, response)); + } } - output + (request_output, response_output) } } From 970c5fcd98b5c02c4745e4ab27bf3732e38cf2bf Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 6 Feb 2024 14:26:53 -0600 Subject: [PATCH 27/99] implement global request/response managers in client & server --- client/src/client.rs | 2 +- client/src/request.rs | 47 ++++++++++++++++++++++++++-------- server/src/request.rs | 46 +++++++++++++++++++++++++-------- server/src/server.rs | 2 +- shared/src/messages/request.rs | 18 ++++++++++++- 5 files changed, 90 insertions(+), 25 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 764089550..f0af6aafa 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -329,7 +329,7 @@ impl Client { &mut connection.base.local_world_manager, ); - let request_id = connection.global_request_manager.create_request_id(channel_kind); + let request_id = connection.global_request_manager.create_request_id(); let message = MessageContainer::from_write(request_box, &mut converter); connection.base.message_manager.send_request( &self.protocol.message_kinds, diff --git a/client/src/request.rs b/client/src/request.rs index 72e1ff89a..e6566d7da 100644 --- a/client/src/request.rs +++ b/client/src/request.rs @@ -1,47 +1,72 @@ +use std::collections::HashMap; + use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer}; // GlobalRequestManager pub struct GlobalRequestManager { - + map: HashMap>, + next_id: u64, } impl GlobalRequestManager { pub fn new() -> Self { Self { - + map: HashMap::new(), + next_id: 0, } } - pub(crate) fn create_request_id(&mut self, channel_kind: &ChannelKind) -> GlobalRequestId { - todo!() + pub(crate) fn create_request_id(&mut self) -> GlobalRequestId { + let id = GlobalRequestId::new(self.next_id); + self.next_id = self.next_id.wrapping_add(1); + + self.map.insert(id, None); + + id } pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option { - todo!() + let Some(response_opt) = self.map.get(request_id) else { + return None; + }; + if response_opt.is_some() { + let response_opt = self.map.remove(request_id).unwrap(); + return Some(response_opt.unwrap()); + } + return None; } pub(crate) fn receive_response(&mut self, request_id: &GlobalRequestId, response: MessageContainer) { - todo!() + let response_opt = self.map.get_mut(request_id).unwrap(); + *response_opt = Some(response); } } + // GlobalResponseManager pub struct GlobalResponseManager { - + map: HashMap, + next_id: u64, } impl GlobalResponseManager { pub fn new() -> Self { Self { - + map: HashMap::new(), + next_id: 0, } } pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, local_response_id: &LocalResponseId) -> GlobalResponseId { - todo!() + let id = GlobalResponseId::new(self.next_id); + self.next_id = self.next_id.wrapping_add(1); + + self.map.insert(id, (channel_kind.clone(), local_response_id.clone())); + + id } - pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option<(ChannelKind, LocalResponseId)> { - todo!() + pub(crate) fn destroy_response_id(&mut self, global_response_id: &GlobalResponseId) -> Option<(ChannelKind, LocalResponseId)> { + self.map.remove(global_response_id) } } \ No newline at end of file diff --git a/server/src/request.rs b/server/src/request.rs index c36c3224d..08ad18183 100644 --- a/server/src/request.rs +++ b/server/src/request.rs @@ -1,49 +1,73 @@ +use std::collections::HashMap; + use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer}; use crate::UserKey; // GlobalRequestManager pub struct GlobalRequestManager { - + map: HashMap)>, + next_id: u64, } impl GlobalRequestManager { pub fn new() -> Self { Self { - + map: HashMap::new(), + next_id: 0, } } - pub(crate) fn create_request_id(&self, user_key: &UserKey, channel_kind: &ChannelKind) -> GlobalRequestId { - todo!() + pub(crate) fn create_request_id(&mut self, user_key: &UserKey) -> GlobalRequestId { + let id = GlobalRequestId::new(self.next_id); + self.next_id = self.next_id.wrapping_add(1); + + self.map.insert(id, (user_key.clone(), None)); + + id } pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option<(UserKey, MessageContainer)> { - todo!() + let Some((_, response_opt)) = self.map.get(request_id) else { + return None; + }; + if response_opt.is_some() { + let (user_key, response_opt) = self.map.remove(request_id).unwrap(); + return Some((user_key, response_opt.unwrap())); + } + return None; } pub(crate) fn receive_response(&mut self, request_id: &GlobalRequestId, response: MessageContainer) { - todo!() + let (_, response_opt) = self.map.get_mut(request_id).unwrap(); + *response_opt = Some(response); } } // GlobalResponseManager pub struct GlobalResponseManager { - + map: HashMap, + next_id: u64, } impl GlobalResponseManager { pub fn new() -> Self { Self { - + map: HashMap::new(), + next_id: 0, } } pub(crate) fn create_response_id(&mut self, user_key: &UserKey, channel_kind: &ChannelKind, local_response_id: &LocalResponseId) -> GlobalResponseId { - todo!() + let id = GlobalResponseId::new(self.next_id); + self.next_id = self.next_id.wrapping_add(1); + + self.map.insert(id, (user_key.clone(), channel_kind.clone(), local_response_id.clone())); + + id } - pub(crate) fn destroy_response_id(&self, global_response_id: &GlobalResponseId) -> Option<(UserKey, ChannelKind, LocalResponseId)> { - todo!() + pub(crate) fn destroy_response_id(&mut self, global_response_id: &GlobalResponseId) -> Option<(UserKey, ChannelKind, LocalResponseId)> { + self.map.remove(global_response_id) } } \ No newline at end of file diff --git a/server/src/server.rs b/server/src/server.rs index 88b06a674..583de7897 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -312,7 +312,7 @@ impl Server { panic!("Requests can only be sent over Bidirectional, Reliable Channels"); } - let request_id = self.global_request_manager.create_request_id(user_key, channel_kind); + let request_id = self.global_request_manager.create_request_id(user_key); let Some(user) = self.users.get(user_key) else { warn!("user does not exist"); diff --git a/shared/src/messages/request.rs b/shared/src/messages/request.rs index 479354ffc..3fb9db40d 100644 --- a/shared/src/messages/request.rs +++ b/shared/src/messages/request.rs @@ -42,7 +42,7 @@ pub struct ResponseReceiveKey { impl ResponseReceiveKey { pub fn new(request_id: GlobalRequestId) -> Self { Self { - request_id: request_id, + request_id, phantom_s: PhantomData, } } @@ -57,7 +57,23 @@ pub struct GlobalRequestId { id: u64, } +impl GlobalRequestId { + pub fn new(id: u64) -> Self { + Self { + id, + } + } +} + #[derive(Clone, Copy, Eq, Hash, PartialEq)] pub struct GlobalResponseId { id: u64, +} + +impl GlobalResponseId { + pub fn new(id: u64) -> Self { + Self { + id, + } + } } \ No newline at end of file From 1159a8d0344d9346edc796d8c484e5194a2fb8a2 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 6 Feb 2024 16:51:40 -0600 Subject: [PATCH 28/99] and done with requests/responses! --- adapters/bevy/client/src/client.rs | 2 +- adapters/bevy/client/src/lib.rs | 2 +- adapters/bevy/server/src/lib.rs | 2 +- adapters/bevy/server/src/server.rs | 7 +-- client/src/client.rs | 14 +++-- client/src/lib.rs | 2 +- demos/bevy/client/src/app.rs | 1 + demos/bevy/client/src/resources.rs | 10 ++-- demos/bevy/client/src/systems/events.rs | 46 +++++++++++++--- demos/bevy/server/src/main.rs | 1 + demos/bevy/server/src/resources.rs | 7 ++- demos/bevy/server/src/systems/events.rs | 52 ++++++++++++++++--- demos/bevy/server/src/systems/init.rs | 4 +- .../bevy/shared/src/messages/basic_request.rs | 16 +++--- server/src/lib.rs | 2 +- server/src/server.rs | 18 +++---- shared/src/messages/channels/channel_kinds.rs | 5 +- shared/src/messages/message_manager.rs | 19 +++++-- shared/src/messages/request.rs | 3 +- 19 files changed, 148 insertions(+), 65 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 6b2d21b0d..5fb2c4dd6 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -87,7 +87,7 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { } /// Requests /// - pub fn send_request(&mut self, request: &Q) -> Option> { + pub fn send_request(&mut self, request: &Q) -> Result, NaiaClientError> { self.client.client.send_request::(request) } diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 67f23b3c6..c579f4797 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -2,7 +2,7 @@ pub use naia_bevy_shared::{ sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, Timer, }; pub use naia_client::{ - shared::{default_channels, Instant, Message}, + shared::{default_channels, Instant, Message, ResponseReceiveKey}, transport, ClientConfig, CommandHistory, ReplicationConfig, }; diff --git a/adapters/bevy/server/src/lib.rs b/adapters/bevy/server/src/lib.rs index 9eba5c7bb..f63aebf4d 100644 --- a/adapters/bevy/server/src/lib.rs +++ b/adapters/bevy/server/src/lib.rs @@ -3,7 +3,7 @@ pub use naia_server::{ shared::{ default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, SerdeErr, SignedInteger, SignedVariableInteger, UnsignedInteger, - UnsignedVariableInteger, + UnsignedVariableInteger, ResponseReceiveKey, }, transport, ReplicationConfig, RoomKey, SerdeBevy as Serde, ServerConfig, UserKey, }; diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index 28dde5b73..61d3308f9 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -5,10 +5,7 @@ use bevy_ecs::{ system::{ResMut, SystemParam, Resource}, }; -use naia_server::{ - shared::SocketConfig, transport::Socket, ReplicationConfig, RoomKey, RoomMut, RoomRef, - Server as NaiaServer, TickBufferMessages, UserKey, UserMut, UserRef, UserScopeMut, -}; +use naia_server::{shared::SocketConfig, transport::Socket, ReplicationConfig, RoomKey, RoomMut, RoomRef, Server as NaiaServer, TickBufferMessages, UserKey, UserMut, UserRef, UserScopeMut, NaiaServerError}; use naia_bevy_shared::{Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick}; @@ -64,7 +61,7 @@ impl<'w> Server<'w> { /// Requests /// - pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Option> { + pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Result, NaiaServerError> { self.server.0.send_request::(user_key, request) } diff --git a/client/src/client.rs b/client/src/client.rs index f0af6aafa..23154a10e 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -297,14 +297,12 @@ impl Client { } // - pub fn send_request(&mut self, request: &Q) -> Option> { + pub fn send_request(&mut self, request: &Q) -> Result, NaiaClientError> { let cloned_request = Q::clone_box(request); // let response_type_id = TypeId::of::(); - let Some(id) = self.send_request_inner(&ChannelKind::of::(), cloned_request) else { - return None; - }; - Some(ResponseReceiveKey::new(id)) + let id = self.send_request_inner(&ChannelKind::of::(), cloned_request)?; + Ok(ResponseReceiveKey::new(id)) } fn send_request_inner( @@ -312,7 +310,7 @@ impl Client { channel_kind: &ChannelKind, // response_type_id: TypeId, request_box: Box, - ) -> Option { + ) -> Result { let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); @@ -322,7 +320,7 @@ impl Client { let Some(connection) = &mut self.server_connection else { warn!("currently not connected to server"); - return None; + return Err(NaiaClientError::Message("currently not connected to server".to_string())); }; let mut converter = EntityConverterMut::new( &self.global_world_manager, @@ -339,7 +337,7 @@ impl Client { message, ); - return Some(request_id); + return Ok(request_id); } /// Sends a Response for a given Request. Returns whether or not was successful. diff --git a/client/src/lib.rs b/client/src/lib.rs index a2876f2cc..145a86fd5 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -17,7 +17,7 @@ pub mod transport; pub mod shared { pub use naia_shared::{ default_channels, sequence_greater_than, Instant, Message, Protocol, Random, SocketConfig, - Tick, GlobalRequestId, GlobalResponseId, + Tick, GlobalRequestId, GlobalResponseId, ResponseReceiveKey }; } pub mod internal { diff --git a/demos/bevy/client/src/app.rs b/demos/bevy/client/src/app.rs index d72d27da9..4d57e8c63 100644 --- a/demos/bevy/client/src/app.rs +++ b/demos/bevy/client/src/app.rs @@ -45,6 +45,7 @@ pub fn run() { events::remove_component_events, events::message_events, events::request_events, + events::response_events, ) .chain() .in_set(ReceiveEvents), diff --git a/demos/bevy/client/src/resources.rs b/demos/bevy/client/src/resources.rs index efe3062c2..0bbb9b1d7 100644 --- a/demos/bevy/client/src/resources.rs +++ b/demos/bevy/client/src/resources.rs @@ -1,9 +1,9 @@ -use std::default::Default; +use std::{collections::HashSet, default::Default}; use bevy::prelude::{ColorMaterial, Entity, Handle, Mesh, Resource}; -use naia_bevy_client::CommandHistory; -use naia_bevy_demo_shared::messages::KeyCommand; +use naia_bevy_client::{CommandHistory, ResponseReceiveKey}; +use naia_bevy_demo_shared::messages::{BasicResponse, KeyCommand}; pub struct OwnedEntity { pub confirmed: Entity, @@ -34,6 +34,8 @@ pub struct Global { pub orange: Handle, pub aqua: Handle, pub circle: Handle, + pub response_keys: HashSet>, + pub request_index: u8, } impl Default for Global { @@ -52,6 +54,8 @@ impl Default for Global { purple: Handle::default(), orange: Handle::default(), aqua: Handle::default(), + response_keys: HashSet::new(), + request_index: 0, } } } diff --git a/demos/bevy/client/src/systems/events.rs b/demos/bevy/client/src/systems/events.rs index 3385b1c05..fa84d37f9 100644 --- a/demos/bevy/client/src/systems/events.rs +++ b/demos/bevy/client/src/systems/events.rs @@ -13,19 +13,16 @@ use naia_bevy_client::{ events::{ ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, InsertComponentEvents, MessageEvents, PublishEntityEvent, RejectEvent, RemoveComponentEvents, SpawnEntityEvent, - UnpublishEntityEvent, UpdateComponentEvents, + UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, }, sequence_greater_than, Client, CommandsExt, Random, Replicate, Tick, }; -use naia_bevy_client::events::RequestEvents; use naia_bevy_demo_shared::{ behavior as shared_behavior, - channels::{EntityAssignmentChannel, PlayerCommandChannel}, + channels::{RequestChannel, EntityAssignmentChannel, PlayerCommandChannel}, components::{Color, ColorValue, Position, Shape, ShapeValue}, - messages::{EntityAssignment, KeyCommand}, + messages::{BasicRequest, BasicResponse, EntityAssignment, KeyCommand}, }; -use naia_bevy_demo_shared::channels::RequestChannel; -use naia_bevy_demo_shared::messages::BasicRequest; use crate::{ components::{Confirmed, Interp, LocalCursor, Predicted}, @@ -168,13 +165,33 @@ pub fn message_events( } pub fn request_events( + mut client: Client

, mut event_reader: EventReader>, ) { for events in event_reader.read() { - for (response_send_key, basic_request) in events.read::() { + for (response_send_key, request) in events.read::() { + info!("Client received Request <- Server: {:?}", request); + let response = BasicResponse::new("ClientResponse".to_string(), request.index); + info!("Client sending Response -> Server: {:?}", response); + client.send_response(&response_send_key, &response); + } + } +} +pub fn response_events( + mut client: Client
, + mut global: ResMut, +) { + let mut finished_response_keys = Vec::new(); + for response_key in &global.response_keys { + if let Some(response) = client.receive_response(response_key) { + info!("Client received Response <- Server: {:?}", response); + finished_response_keys.push(response_key.clone()); } } + for response_key in finished_response_keys { + global.response_keys.remove(&response_key); + } } pub fn spawn_entity_events(mut event_reader: EventReader>) { @@ -373,6 +390,21 @@ pub fn tick_events( for event in tick_reader.read() { let client_tick = event.tick; + + // Send a request to server + if client_tick % 100 == 0 { + let request = BasicRequest::new("ClientRequest".to_string(), global.request_index); + global.request_index = global.request_index.wrapping_add(1); + + info!("Client sending Request -> Server: {:?}", request); + let Ok(response_key) = client.send_request::(&request) else { + info!("Failed to send request to server"); + return; + }; + global.response_keys.insert(response_key); + } + + // Command History if !global.command_history.can_insert(&client_tick) { // History is full continue; diff --git a/demos/bevy/server/src/main.rs b/demos/bevy/server/src/main.rs index a8f77d5a3..6ca64889b 100644 --- a/demos/bevy/server/src/main.rs +++ b/demos/bevy/server/src/main.rs @@ -48,6 +48,7 @@ fn main() { events::update_component_events, events::remove_component_events, events::request_events, + events::response_events, ) .chain() .in_set(ReceiveEvents), diff --git a/demos/bevy/server/src/resources.rs b/demos/bevy/server/src/resources.rs index 00b897ea7..a5b6a3980 100644 --- a/demos/bevy/server/src/resources.rs +++ b/demos/bevy/server/src/resources.rs @@ -1,12 +1,15 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use bevy_ecs::{entity::Entity, prelude::Resource}; -use naia_bevy_server::{RoomKey, UserKey}; +use naia_bevy_demo_shared::messages::BasicResponse; +use naia_bevy_server::{RoomKey, UserKey, ResponseReceiveKey}; #[derive(Resource)] pub struct Global { pub main_room_key: RoomKey, pub user_to_square_map: HashMap, pub square_to_user_map: HashMap, + pub response_keys: HashSet>, + pub request_index: u8, } diff --git a/demos/bevy/server/src/systems/events.rs b/demos/bevy/server/src/systems/events.rs index db08355c0..32090bcad 100644 --- a/demos/bevy/server/src/systems/events.rs +++ b/demos/bevy/server/src/systems/events.rs @@ -8,20 +8,17 @@ use naia_bevy_server::{ events::{ AuthEvents, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, InsertComponentEvents, PublishEntityEvent, RemoveComponentEvents, SpawnEntityEvent, - TickEvent, UnpublishEntityEvent, UpdateComponentEvents, + TickEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, }, CommandsExt, Random, ReplicationConfig, Server, }; use naia_bevy_demo_shared::{ behavior as shared_behavior, - channels::{EntityAssignmentChannel, PlayerCommandChannel}, + channels::{RequestChannel, EntityAssignmentChannel, PlayerCommandChannel}, components::{Color, ColorValue, Position, Shape, ShapeValue}, - messages::{Auth, EntityAssignment, KeyCommand}, + messages::{Auth, EntityAssignment, KeyCommand, BasicRequest, BasicResponse}, }; -use naia_bevy_demo_shared::channels::RequestChannel; -use naia_bevy_demo_shared::messages::BasicRequest; -use naia_bevy_server::events::RequestEvents; use crate::resources::Global; @@ -138,6 +135,7 @@ pub fn error_events(mut event_reader: EventReader) { pub fn tick_events( mut server: Server, mut position_query: Query<&mut Position>, + mut global: ResMut, mut tick_reader: EventReader, ) { let mut has_ticked = false; @@ -157,6 +155,22 @@ pub fn tick_events( }; shared_behavior::process_command(&key_command, &mut position); } + + // Send a request to all clients + if server_tick % 100 == 0 { + + for user_key in server.user_keys() { + let request = BasicRequest::new("ServerRequest".to_string(), global.request_index); + global.request_index = global.request_index.wrapping_add(1); + let user = server.user(&user_key); + info!("Server sending Request -> Client ({}): {:?}", user.address(), request); + let Ok(response_key) = server.send_request::(&user_key, &request) else { + info!("Failed to send request to user: {:?}", user_key); + continue; + }; + global.response_keys.insert(response_key); + } + } } if has_ticked { @@ -175,15 +189,37 @@ pub fn tick_events( } pub fn request_events( + mut server: Server, mut event_reader: EventReader, ) { for events in event_reader.read() { - for (user_key, response_send_key, basic_request) in events.read::() { - todo!() + for (user_key, response_send_key, request) in events.read::() { + let user = server.user(&user_key); + info!("Server received Request <- Client({}): {:?}", user.address(), request); + let response = BasicResponse::new("ServerResponse".to_string(), request.index); + info!("Server sending Response -> Client({}): {:?}", user.address(), response); + server.send_response(&response_send_key, &response); } } } +pub fn response_events( + mut server: Server, + mut global: ResMut, +) { + let mut finished_response_keys = Vec::new(); + for response_key in &global.response_keys { + if let Some((user_key, response)) = server.receive_response(response_key) { + let user = server.user(&user_key); + info!("Server received Response <- Client({:?}): {:?}", user.address(), response); + finished_response_keys.push(response_key.clone()); + } + } + for response_key in finished_response_keys { + global.response_keys.remove(&response_key); + } +} + pub fn spawn_entity_events( mut commands: Commands, mut server: Server, diff --git a/demos/bevy/server/src/systems/init.rs b/demos/bevy/server/src/systems/init.rs index 84e7d0015..c1091f8d1 100644 --- a/demos/bevy/server/src/systems/init.rs +++ b/demos/bevy/server/src/systems/init.rs @@ -1,4 +1,4 @@ -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use bevy_ecs::system::Commands; use bevy_log::info; @@ -34,6 +34,8 @@ pub fn init(mut commands: Commands, mut server: Server) { main_room_key, user_to_square_map: HashMap::new(), square_to_user_map: HashMap::new(), + response_keys: HashSet::new(), + request_index: 0, }; // Insert Global Resource diff --git a/demos/bevy/shared/src/messages/basic_request.rs b/demos/bevy/shared/src/messages/basic_request.rs index 8b5e411ea..34eb3db2c 100644 --- a/demos/bevy/shared/src/messages/basic_request.rs +++ b/demos/bevy/shared/src/messages/basic_request.rs @@ -1,8 +1,9 @@ use naia_bevy_shared::{Message, Request, Response}; -#[derive(Message)] +#[derive(Message, Debug)] pub struct BasicRequest { pub contents: String, + pub index: u8, } impl Request for BasicRequest { @@ -10,22 +11,23 @@ impl Request for BasicRequest { } impl BasicRequest { - pub fn new(contents: String) -> Self { - Self { contents } + pub fn new(contents: String, index: u8) -> Self { + Self { contents, index } } } -#[derive(Message)] +#[derive(Message, Eq, PartialEq, Hash, Debug)] pub struct BasicResponse { pub contents: String, + pub index: u8, } impl Response for BasicResponse { - type Request = BasicRequest; + } impl BasicResponse { - pub fn new(contents: String) -> Self { - Self { contents } + pub fn new(contents: String, index: u8) -> Self { + Self { contents, index } } } \ No newline at end of file diff --git a/server/src/lib.rs b/server/src/lib.rs index b6422095c..248cf7f33 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -18,7 +18,7 @@ pub mod shared { pub use naia_shared::{ default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, Random, Serde, SerdeErr, SignedInteger, SignedVariableInteger, SocketConfig, - UnsignedInteger, UnsignedVariableInteger, GlobalResponseId, + UnsignedInteger, UnsignedVariableInteger, GlobalResponseId, ResponseReceiveKey, }; } pub mod internal { diff --git a/server/src/server.rs b/server/src/server.rs index 583de7897..18c439df3 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -288,23 +288,19 @@ impl Server { } // - pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Option> { + pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Result, NaiaServerError> { let cloned_request = Q::clone_box(request); - // let response_type_id = TypeId::of::(); - let Some(id) = self.send_request_inner(user_key, &ChannelKind::of::(), cloned_request) else { - return None; - }; - Some(ResponseReceiveKey::new(id)) + let id = self.send_request_inner(user_key, &ChannelKind::of::(), cloned_request)?; + Ok(ResponseReceiveKey::new(id)) } fn send_request_inner( &mut self, user_key: &UserKey, channel_kind: &ChannelKind, - // response_type_id: TypeId, request_box: Box, - ) -> Option { + ) -> Result { let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); @@ -316,11 +312,11 @@ impl Server { let Some(user) = self.users.get(user_key) else { warn!("user does not exist"); - return None; + return Err(NaiaServerError::Message("user does not exist".to_string())); }; let Some(connection) = self.user_connections.get_mut(&user.address) else { warn!("currently not connected to user"); - return None; + return Err(NaiaServerError::Message("currently not connected to user".to_string())); }; let mut converter = EntityConverterMut::new( &self.global_world_manager, @@ -336,7 +332,7 @@ impl Server { message, ); - return Some(request_id); + return Ok(request_id); } /// Sends a Response for a given Request. Returns whether or not was successful. diff --git a/shared/src/messages/channels/channel_kinds.rs b/shared/src/messages/channels/channel_kinds.rs index 2bfba7099..f50ab6447 100644 --- a/shared/src/messages/channels/channel_kinds.rs +++ b/shared/src/messages/channels/channel_kinds.rs @@ -1,5 +1,7 @@ use std::{any::TypeId, collections::HashMap}; +use log::info; + use naia_serde::{BitReader, BitWrite, ConstBitLength, Serde, SerdeErr}; use crate::messages::channels::channel::{Channel, ChannelSettings}; @@ -7,7 +9,7 @@ use crate::messages::channels::channel::{Channel, ChannelSettings}; type NetId = u16; /// ChannelKind - should be one unique value for each type of Channel -#[derive(Eq, Hash, Copy, Clone, PartialEq)] +#[derive(Eq, Hash, Copy, Clone, PartialEq, Debug)] pub struct ChannelKind { type_id: TypeId, } @@ -61,6 +63,7 @@ impl ChannelKinds { pub fn add_channel(&mut self, settings: ChannelSettings) { let channel_kind = ChannelKind::of::(); + info!("ChannelKinds adding channel: {:?}", channel_kind); let net_id = self.current_net_id; self.kind_map.insert(channel_kind, (net_id, settings)); self.net_id_map.insert(net_id, channel_kind); diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index f30536b02..b137d7ee6 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -1,5 +1,7 @@ use std::{collections::HashMap, hash::Hash}; +use log::info; + use naia_serde::{BitReader, BitWrite, BitWriter, ConstBitLength, Serde, SerdeErr}; use naia_socket_shared::Instant; @@ -49,6 +51,7 @@ impl MessageManager { // initialize senders let mut channel_senders = HashMap::>::new(); for (channel_kind, channel_settings) in channel_kinds.channels() { + info!("initialize senders for channel: {:?}", channel_kind); match &host_type { HostType::Server => { if !channel_settings.can_send_to_client() { @@ -342,12 +345,18 @@ impl MessageManager { let mut response_output = Vec::new(); for (channel_kind, channel) in &mut self.channel_receivers { let (requests, responses) = channel.receive_requests_and_responses(); - request_output.push((channel_kind.clone(), requests)); + if !requests.is_empty() { + request_output.push((channel_kind.clone(), requests)); + } - let channel_sender = self.channel_senders.get_mut(channel_kind).unwrap(); - for (local_request_id, response) in responses { - let global_request_id = channel_sender.process_incoming_response(&local_request_id).unwrap(); - response_output.push((global_request_id, response)); + if !responses.is_empty() { + let Some(channel_sender) = self.channel_senders.get_mut(channel_kind) else { + panic!("Channel not configured correctly! Cannot send message on channel: {:?}", channel_kind); + }; + for (local_request_id, response) in responses { + let global_request_id = channel_sender.process_incoming_response(&local_request_id).unwrap(); + response_output.push((global_request_id, response)); + } } } (request_output, response_output) diff --git a/shared/src/messages/request.rs b/shared/src/messages/request.rs index 3fb9db40d..5db4cbbd1 100644 --- a/shared/src/messages/request.rs +++ b/shared/src/messages/request.rs @@ -9,7 +9,6 @@ pub trait Request: Message { // Response pub trait Response: Message { - type Request: Request; } // ResponseSendKey @@ -33,7 +32,7 @@ impl ResponseSendKey { } // ResponseReceiveKey -#[derive(Clone, Eq, PartialEq, Hash)] +#[derive(Clone, Eq, PartialEq, Hash, Copy)] pub struct ResponseReceiveKey { request_id: GlobalRequestId, phantom_s: PhantomData, From 522544f7b07706b28397be914410118a6e5608bb Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 6 Feb 2024 17:48:50 -0600 Subject: [PATCH 29/99] get rid of unecessary type on function --- adapters/bevy/client/src/plugin.rs | 2 +- adapters/bevy/server/src/plugin.rs | 2 +- adapters/bevy/shared/src/world_data.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index f85ea89ad..69defe320 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -52,7 +52,7 @@ impl PluginType for Plugin { let mut config = self.config.lock().unwrap().deref_mut().take().unwrap(); let mut world_data = config.protocol.take_world_data(); - world_data.add_systems::(app); + world_data.add_systems(app); if let Some(old_world_data) = app.world.remove_resource::() { world_data.merge(old_world_data); diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index 2d324c413..7c1428451 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -51,7 +51,7 @@ impl PluginType for Plugin { let mut config = self.config.lock().unwrap().deref_mut().take().unwrap(); let world_data = config.protocol.take_world_data(); - world_data.add_systems::(app); + world_data.add_systems(app); app.insert_resource(world_data); let server = Server::::new(config.server_config, config.protocol.into()); diff --git a/adapters/bevy/shared/src/world_data.rs b/adapters/bevy/shared/src/world_data.rs index 652173106..9d6ef6d0a 100644 --- a/adapters/bevy/shared/src/world_data.rs +++ b/adapters/bevy/shared/src/world_data.rs @@ -48,7 +48,7 @@ impl WorldData { self.kind_to_accessor_map.extend(other.kind_to_accessor_map); } - pub fn add_systems(&self, app: &mut App) { + pub fn add_systems(&self, app: &mut App) { for (_kind, accessor_any) in &self.kind_to_accessor_map { let accessor = accessor_any .downcast_ref::>() From 87359df60aaecfa450e83a4f3ec5a6ee6cc95afe Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Wed, 7 Feb 2024 21:20:28 -0600 Subject: [PATCH 30/99] support messages with generic marker types --- demos/basic/client/app/src/app.rs | 7 +- demos/basic/server/src/app.rs | 9 +- demos/basic/shared/src/lib.rs | 2 +- demos/basic/shared/src/protocol/mod.rs | 4 +- .../shared/src/protocol/string_message.rs | 8 +- shared/derive/src/message.rs | 137 +++++++++++++++--- shared/serde/src/impls.rs | 1 + shared/serde/src/impls/phantom.rs | 55 +++++++ shared/src/messages/channels/channel_kinds.rs | 4 +- shared/src/messages/message_manager.rs | 7 +- 10 files changed, 197 insertions(+), 37 deletions(-) create mode 100644 shared/serde/src/impls/phantom.rs diff --git a/demos/basic/client/app/src/app.rs b/demos/basic/client/app/src/app.rs index bfa841855..60d92ca32 100644 --- a/demos/basic/client/app/src/app.rs +++ b/demos/basic/client/app/src/app.rs @@ -16,7 +16,7 @@ use naia_client::{ use naia_demo_world::{Entity, World}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest}; +use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest, MyMarker}; type Client = NaiaClient; @@ -76,7 +76,7 @@ impl App { for server_address in events.read::() { info!("Client disconnected from: {}", server_address); } - for message in events.read::>() { + for message in events.read::>>() { let message_contents = &(*message.contents); info!("Client recv <- {}", message_contents); @@ -138,8 +138,5 @@ impl App { info!("Client Error: {}", error); return; } - for (response_send_key, message) in events.read::>() { - - } } } diff --git a/demos/basic/server/src/app.rs b/demos/basic/server/src/app.rs index d2e11a182..aeadcee01 100644 --- a/demos/basic/server/src/app.rs +++ b/demos/basic/server/src/app.rs @@ -8,7 +8,7 @@ use naia_server::{ use naia_demo_world::{Entity, World, WorldRefType}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest}; +use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest, MyMarker}; type Server = NaiaServer; @@ -107,7 +107,7 @@ impl App { info!("Naia Server disconnected from: {:?}", user.address); } for (user_key, message) in - events.read::>() + events.read::>>() { let message_contents = &(*message.contents); info!( @@ -129,7 +129,7 @@ impl App { new_message_contents ); - let new_message = StringMessage::new(new_message_contents); + let new_message = StringMessage::::new(new_message_contents); self.server .send_message::(&user_key, &new_message); } @@ -172,9 +172,6 @@ impl App { for error in events.read::() { info!("Naia Server Error: {}", error); } - for (user_key, response_key, request) in events.read::>() { - - } } } } diff --git a/demos/basic/shared/src/lib.rs b/demos/basic/shared/src/lib.rs index 303b02fe8..9b603e23d 100644 --- a/demos/basic/shared/src/lib.rs +++ b/demos/basic/shared/src/lib.rs @@ -1,3 +1,3 @@ mod protocol; -pub use protocol::{protocol, Auth, Character, StringMessage, BasicRequest, BasicResponse}; +pub use protocol::{protocol, Auth, Character, StringMessage, BasicRequest, BasicResponse, MyMarker}; diff --git a/demos/basic/shared/src/protocol/mod.rs b/demos/basic/shared/src/protocol/mod.rs index 9b2585d7c..4a279d552 100644 --- a/demos/basic/shared/src/protocol/mod.rs +++ b/demos/basic/shared/src/protocol/mod.rs @@ -12,6 +12,8 @@ pub use character::Character; pub use string_message::StringMessage; pub use basic_request::{BasicRequest, BasicResponse}; +pub struct MyMarker; + // Protocol Build pub fn protocol() -> Protocol { Protocol::builder() @@ -22,7 +24,7 @@ pub fn protocol() -> Protocol { .add_default_channels() // Messages .add_message::() - .add_message::() + .add_message::>() // Requests .add_request::() // Components diff --git a/demos/basic/shared/src/protocol/string_message.rs b/demos/basic/shared/src/protocol/string_message.rs index 1d0c8fe74..6b2416407 100644 --- a/demos/basic/shared/src/protocol/string_message.rs +++ b/demos/basic/shared/src/protocol/string_message.rs @@ -1,12 +1,14 @@ + use naia_shared::Message; #[derive(Message)] -pub struct StringMessage { +pub struct StringMessage { pub contents: String, + phantom_t: std::marker::PhantomData, } -impl StringMessage { +impl StringMessage { pub fn new(contents: String) -> Self { - Self { contents } + Self { contents, phantom_t: std::marker::PhantomData } } } diff --git a/shared/derive/src/message.rs b/shared/derive/src/message.rs index 2f4fdb701..5184dc717 100644 --- a/shared/derive/src/message.rs +++ b/shared/derive/src/message.rs @@ -1,6 +1,6 @@ use proc_macro2::{Span, TokenStream}; use quote::{format_ident, quote}; -use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident, Index, LitStr, Member, Type}; +use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident, Index, LitStr, Member, Type, Generics, GenericParam}; use super::shared::{get_struct_type, StructType}; @@ -15,16 +15,18 @@ pub fn message_impl( // Helper Properties let struct_type = get_struct_type(&input); let fields = get_fields(&input); + let (untyped_generics, typed_generics, turbofish) = get_generics(&input); // Names let struct_name = input.ident; - let struct_name_str = LitStr::new(&struct_name.to_string(), struct_name.span()); + let struct_name_str = LitStr::new(format!("{}{}", &struct_name.to_string(), &untyped_generics.to_string()).as_str(), struct_name.span()); let lowercase_struct_name = Ident::new( struct_name.to_string().to_lowercase().as_str(), Span::call_site(), ); let module_name = format_ident!("define_{}", lowercase_struct_name); let builder_name = format_ident!("{}Builder", struct_name); + let builder_generic_fields = get_builder_generic_fields(&input.generics); // Methods let clone_method = get_clone_method(&fields, &struct_type); @@ -32,8 +34,9 @@ pub fn message_impl( let relations_complete_method = get_relations_complete_method(&fields, &struct_type); let bit_length_method = get_bit_length_method(&fields, &struct_type); let write_method = get_write_method(&fields, &struct_type); - let create_builder_method = get_create_builder_method(&builder_name); - let read_method = get_read_method(&struct_name, &fields, &struct_type); + let create_builder_method = get_create_builder_method(&builder_name, &turbofish); + let builder_new_method = get_builder_new_method(&typed_generics, &builder_name, &untyped_generics, &input.generics); + let builder_read_method = get_builder_read_method(&struct_name, &fields, &struct_type, &turbofish); let is_fragment_method = get_is_fragment_method(is_fragment); let is_request_method = get_is_request_method(is_request); @@ -47,14 +50,15 @@ pub fn message_impl( }; use super::*; - struct #builder_name; - impl MessageBuilder for #builder_name { - #read_method + struct #builder_name #typed_generics #builder_generic_fields + #builder_new_method + impl #typed_generics MessageBuilder for #builder_name #untyped_generics { + #builder_read_method } - impl Message for #struct_name { + impl #typed_generics Message for #struct_name #untyped_generics { fn kind(&self) -> MessageKind { - MessageKind::of::<#struct_name>() + MessageKind::of::<#struct_name #untyped_generics>() } fn to_boxed_any(self: Box) -> Box { self @@ -67,12 +71,12 @@ pub fn message_impl( #relations_complete_method #write_method } - impl Named for #struct_name { + impl #typed_generics Named for #struct_name #untyped_generics { fn name(&self) -> String { return #struct_name_str.to_string(); } } - impl Clone for #struct_name { + impl #typed_generics Clone for #struct_name #untyped_generics { #clone_method } } @@ -241,10 +245,11 @@ fn get_relations_complete_method(fields: &[Field], struct_type: &StructType) -> } } -pub fn get_read_method( +pub fn get_builder_read_method( struct_name: &Ident, fields: &[Field], struct_type: &StructType, + turbofish: &TokenStream, ) -> TokenStream { let mut field_names = quote! {}; for field in fields.iter() { @@ -287,14 +292,14 @@ pub fn get_read_method( let struct_build = match *struct_type { StructType::Struct => { quote! { - #struct_name { + #struct_name #turbofish { #field_names } } } StructType::TupleStruct => { quote! { - #struct_name ( + #struct_name #turbofish ( #field_names ) } @@ -383,10 +388,15 @@ fn get_bit_length_method(fields: &[Field], struct_type: &StructType) -> TokenStr } } -pub fn get_create_builder_method(builder_name: &Ident) -> TokenStream { +pub fn get_create_builder_method(builder_name: &Ident, turbofish: &TokenStream) -> TokenStream { + + let builder_new = quote! { + #builder_name #turbofish::new() + }; + quote! { fn create_builder() -> Box where Self:Sized { - Box::new(#builder_name) + Box::new(#builder_new) } } } @@ -443,7 +453,7 @@ fn get_fields(input: &DeriveInput) -> Vec { Fields::Unit => {} } } else { - panic!("Can only derive Replicate on a struct"); + panic!("Can only derive Message on a struct"); } fields @@ -466,6 +476,99 @@ fn get_field_name(field: &Field, index: usize, struct_type: &StructType) -> Memb } } +fn get_generics(input: &DeriveInput) -> (TokenStream, TokenStream, TokenStream) { + let generics = &input.generics; + if generics.lt_token.is_none() { + return (quote! {}, quote! {}, quote! {}); + } + + let (impl_generics, ty_generics, _) = generics.split_for_impl(); + let typed_generics = quote! { + #impl_generics + }; + let untyped_generics = quote! { + #ty_generics + }; + let tf_generics = ty_generics.as_turbofish(); + let turbofish = quote! { + #tf_generics + }; + (untyped_generics, typed_generics, turbofish) +} + +fn get_builder_generic_fields(generics: &Generics) -> TokenStream { + if generics.gt_token.is_none() { + return quote! { ; }; + } + + let mut output = quote! {}; + + for param in generics.params.iter() { + let GenericParam::Type(type_param) = param else { + panic!("Only type parameters are supported for now"); + }; + + let uppercase_letter = &type_param.ident; + let field_name = format_ident!("phantom_{}", type_param.ident.to_string().to_lowercase()); + let new_output_right = quote! { + #field_name: std::marker::PhantomData<#uppercase_letter>, + }; + let new_output_result = quote! { + #output + #new_output_right + }; + output = new_output_result; + } + + quote! { + { #output } + } +} + +pub fn get_builder_new_method( + typed_generics: &TokenStream, + builder_name: &Ident, + untyped_generics: &TokenStream, + input_generics: &Generics, +) -> TokenStream { + + let fn_impl = if input_generics.gt_token.is_none() { + quote! { return Self; } + } else { + let mut output = quote! {}; + + for param in input_generics.params.iter() { + let GenericParam::Type(type_param) = param else { + panic!("Only type parameters are supported for now"); + }; + + let field_name = format_ident!("phantom_{}", type_param.ident.to_string().to_lowercase()); + let new_output_right = quote! { + #field_name: std::marker::PhantomData, + }; + let new_output_result = quote! { + #output + #new_output_right + }; + output = new_output_result; + } + + quote! { + Self { + #output + } + } + }; + + quote! { + impl #typed_generics #builder_name #untyped_generics { + pub fn new() -> Self { + #fn_impl + } + } + } +} + const UNNAMED_FIELD_PREFIX: &'static str = "unnamed_field_"; fn get_variable_name_for_unnamed_field(index: usize, span: Span) -> Ident { Ident::new(&format!("{}{}", UNNAMED_FIELD_PREFIX, index), span) diff --git a/shared/serde/src/impls.rs b/shared/serde/src/impls.rs index 3e6032e1a..1243442a8 100644 --- a/shared/serde/src/impls.rs +++ b/shared/serde/src/impls.rs @@ -6,3 +6,4 @@ mod scalars; mod string; mod tuple; mod vector; +mod phantom; diff --git a/shared/serde/src/impls/phantom.rs b/shared/serde/src/impls/phantom.rs new file mode 100644 index 000000000..0dcaa97c7 --- /dev/null +++ b/shared/serde/src/impls/phantom.rs @@ -0,0 +1,55 @@ +use std::marker::PhantomData; + +use crate::{ + bit_reader::BitReader, + bit_writer::BitWrite, + error::SerdeErr, + serde::{ConstBitLength, Serde}, +}; + +// Unit // + +impl Serde for PhantomData { + fn ser(&self, _: &mut dyn BitWrite) {} + + fn de(_: &mut BitReader) -> Result { + Ok(Self) + } + + fn bit_length(&self) -> u32 { + ::const_bit_length() + } +} + +impl ConstBitLength for PhantomData { + fn const_bit_length() -> u32 { + 0 + } +} + +// tests + +#[cfg(test)] +mod phantom_tests { + use std::marker::PhantomData; + use crate::{bit_reader::BitReader, bit_writer::BitWriter, serde::Serde}; + + #[test] + fn read_write() { + // Write + let mut writer = BitWriter::new(); + + let in_phantom = PhantomData::; + + in_phantom.ser(&mut writer); + + let buffer = writer.to_bytes(); + + //Read + let mut reader = BitReader::new(&buffer); + + let out_phantom = Serde::de(&mut reader).unwrap(); + + assert_eq!(in_phantom, out_phantom); + } +} \ No newline at end of file diff --git a/shared/src/messages/channels/channel_kinds.rs b/shared/src/messages/channels/channel_kinds.rs index f50ab6447..a29be4194 100644 --- a/shared/src/messages/channels/channel_kinds.rs +++ b/shared/src/messages/channels/channel_kinds.rs @@ -1,7 +1,5 @@ use std::{any::TypeId, collections::HashMap}; -use log::info; - use naia_serde::{BitReader, BitWrite, ConstBitLength, Serde, SerdeErr}; use crate::messages::channels::channel::{Channel, ChannelSettings}; @@ -63,7 +61,7 @@ impl ChannelKinds { pub fn add_channel(&mut self, settings: ChannelSettings) { let channel_kind = ChannelKind::of::(); - info!("ChannelKinds adding channel: {:?}", channel_kind); + //info!("ChannelKinds adding channel: {:?}", channel_kind); let net_id = self.current_net_id; self.kind_map.insert(channel_kind, (net_id, settings)); self.net_id_map.insert(net_id, channel_kind); diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index b137d7ee6..364920d93 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -51,7 +51,7 @@ impl MessageManager { // initialize senders let mut channel_senders = HashMap::>::new(); for (channel_kind, channel_settings) in channel_kinds.channels() { - info!("initialize senders for channel: {:?}", channel_kind); + //info!("initialize senders for channel: {:?}", channel_kind); match &host_type { HostType::Server => { if !channel_settings.can_send_to_client() { @@ -344,6 +344,11 @@ impl MessageManager { let mut request_output = Vec::new(); let mut response_output = Vec::new(); for (channel_kind, channel) in &mut self.channel_receivers { + + if !self.channel_settings.get(channel_kind).unwrap().can_request_and_respond() { + continue; + } + let (requests, responses) = channel.receive_requests_and_responses(); if !requests.is_empty() { request_output.push((channel_kind.clone(), requests)); From db15decefc8181a9833a5259b4872dbae346ce37 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Wed, 7 Feb 2024 21:23:37 -0600 Subject: [PATCH 31/99] test out actual generic value (not marker) --- demos/basic/server/src/app.rs | 2 +- demos/basic/shared/src/protocol/mod.rs | 3 ++- demos/basic/shared/src/protocol/string_message.rs | 12 ++++++------ 3 files changed, 9 insertions(+), 8 deletions(-) diff --git a/demos/basic/server/src/app.rs b/demos/basic/server/src/app.rs index aeadcee01..67ed5224a 100644 --- a/demos/basic/server/src/app.rs +++ b/demos/basic/server/src/app.rs @@ -129,7 +129,7 @@ impl App { new_message_contents ); - let new_message = StringMessage::::new(new_message_contents); + let new_message = StringMessage::::new(new_message_contents, MyMarker); self.server .send_message::(&user_key, &new_message); } diff --git a/demos/basic/shared/src/protocol/mod.rs b/demos/basic/shared/src/protocol/mod.rs index 4a279d552..0c24a4873 100644 --- a/demos/basic/shared/src/protocol/mod.rs +++ b/demos/basic/shared/src/protocol/mod.rs @@ -1,6 +1,6 @@ use std::time::Duration; -use naia_shared::{LinkConditionerConfig, Protocol}; +use naia_shared::{LinkConditionerConfig, Protocol, Serde}; mod auth; mod character; @@ -12,6 +12,7 @@ pub use character::Character; pub use string_message::StringMessage; pub use basic_request::{BasicRequest, BasicResponse}; +#[derive(Serde, PartialEq, Clone)] pub struct MyMarker; // Protocol Build diff --git a/demos/basic/shared/src/protocol/string_message.rs b/demos/basic/shared/src/protocol/string_message.rs index 6b2416407..e2436a709 100644 --- a/demos/basic/shared/src/protocol/string_message.rs +++ b/demos/basic/shared/src/protocol/string_message.rs @@ -1,14 +1,14 @@ -use naia_shared::Message; +use naia_shared::{Message, Serde}; #[derive(Message)] -pub struct StringMessage { +pub struct StringMessage { pub contents: String, - phantom_t: std::marker::PhantomData, + something: T, } -impl StringMessage { - pub fn new(contents: String) -> Self { - Self { contents, phantom_t: std::marker::PhantomData } +impl StringMessage { + pub fn new(contents: String, something: T) -> Self { + Self { contents, something } } } From ec1a2bd515027d3b15bf59b1de532a08c35942ce Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Wed, 7 Feb 2024 22:07:39 -0600 Subject: [PATCH 32/99] components can use marker structs now --- demos/basic/client/app/src/app.rs | 12 +-- demos/basic/server/src/app.rs | 10 +-- demos/basic/shared/src/protocol/character.rs | 7 +- demos/basic/shared/src/protocol/mod.rs | 2 +- shared/derive/src/message.rs | 57 +----------- shared/derive/src/replicate.rs | 91 +++++++++++--------- shared/derive/src/shared.rs | 53 +++++++++++- shared/src/messages/message_manager.rs | 6 +- 8 files changed, 125 insertions(+), 113 deletions(-) diff --git a/demos/basic/client/app/src/app.rs b/demos/basic/client/app/src/app.rs index 60d92ca32..fbaafb99f 100644 --- a/demos/basic/client/app/src/app.rs +++ b/demos/basic/client/app/src/app.rs @@ -10,13 +10,13 @@ use naia_client::{ shared::{default_channels::UnorderedReliableChannel, SocketConfig}, transport::webrtc, Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, - DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RequestEvent, RejectEvent, + DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, RemoveComponentEvent, SpawnEntityEvent, UpdateComponentEvent, }; use naia_demo_world::{Entity, World}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest, MyMarker}; +use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, MyMarker}; type Client = NaiaClient; @@ -93,7 +93,7 @@ impl App { if let Some(_character) = self .client .entity(self.world.proxy(), &entity) - .component::() + .component::>() { // info!( // "creation of Character - x: {}, y: {}, name: {} {}", @@ -107,11 +107,11 @@ impl App { for _ in events.read::() { // info!("deletion of Character entity"); } - for (_, entity) in events.read::>() { + for (_, entity) in events.read::>>() { if let Some(_character) = self .client .entity(self.world.proxy(), &entity) - .component::() + .component::>() { // info!( // "update of Character - x: {}, y: {}, name: {} {}", @@ -122,7 +122,7 @@ impl App { // ); } } - for (_, _character) in events.read::>() { + for (_, _character) in events.read::>>() { // info!( // "data delete of Character - x: {}, y: {}, name: {} {}", // *character.x, diff --git a/demos/basic/server/src/app.rs b/demos/basic/server/src/app.rs index 67ed5224a..4c0ae793b 100644 --- a/demos/basic/server/src/app.rs +++ b/demos/basic/server/src/app.rs @@ -2,13 +2,13 @@ use std::{thread::sleep, time::Duration}; use naia_server::{ shared::default_channels::UnorderedReliableChannel, transport::webrtc, AuthEvent, ConnectEvent, - DisconnectEvent, ErrorEvent, MessageEvent, RequestEvent, RoomKey, Server as NaiaServer, ServerConfig, + DisconnectEvent, ErrorEvent, MessageEvent, RoomKey, Server as NaiaServer, ServerConfig, TickEvent, }; use naia_demo_world::{Entity, World, WorldRefType}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, BasicRequest, MyMarker}; +use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, MyMarker}; type Server = NaiaServer; @@ -59,7 +59,7 @@ impl App { count += 1; // Create a Character - let character = Character::new((count * 4) as u8, 0, first, last); + let character = Character::::new((count * 4) as u8, 0, first, last); let character_key = server .spawn_entity(world.proxy_mut()) .insert_component(character) @@ -140,7 +140,7 @@ impl App { if let Some(mut character) = self .server .entity_mut(self.world.proxy_mut(), &entity) - .component::() + .component::>() { character.step(); } @@ -151,7 +151,7 @@ impl App { let server = &mut self.server; let world = &self.world; for (_, user_key, entity) in server.scope_checks() { - if let Some(character) = world.proxy().component::(&entity) { + if let Some(character) = world.proxy().component::>(&entity) { let x = *character.x; if (5..=15).contains(&x) { server.user_scope(&user_key).include(&entity); diff --git a/demos/basic/shared/src/protocol/character.rs b/demos/basic/shared/src/protocol/character.rs index 4d8c93c83..ba84ab183 100644 --- a/demos/basic/shared/src/protocol/character.rs +++ b/demos/basic/shared/src/protocol/character.rs @@ -1,3 +1,4 @@ + use naia_shared::{Property, Replicate, Serde}; /// Here's an example of a Custom Property @@ -10,15 +11,17 @@ pub struct FullName { } #[derive(Replicate)] -pub struct Character { +pub struct Character { + phantom_t: std::marker::PhantomData, pub x: Property, pub y: Property, pub fullname: Property, } -impl Character { +impl Character { pub fn new(x: u8, y: u8, first: &str, last: &str) -> Self { Self::new_complete( + std::marker::PhantomData, x, y, FullName { diff --git a/demos/basic/shared/src/protocol/mod.rs b/demos/basic/shared/src/protocol/mod.rs index 0c24a4873..567007351 100644 --- a/demos/basic/shared/src/protocol/mod.rs +++ b/demos/basic/shared/src/protocol/mod.rs @@ -29,7 +29,7 @@ pub fn protocol() -> Protocol { // Requests .add_request::() // Components - .add_component::() + .add_component::>() // Build Protocol .build() } diff --git a/shared/derive/src/message.rs b/shared/derive/src/message.rs index 5184dc717..681100a1b 100644 --- a/shared/derive/src/message.rs +++ b/shared/derive/src/message.rs @@ -2,7 +2,7 @@ use proc_macro2::{Span, TokenStream}; use quote::{format_ident, quote}; use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident, Index, LitStr, Member, Type, Generics, GenericParam}; -use super::shared::{get_struct_type, StructType}; +use super::shared::{get_builder_generic_fields, get_generics, get_struct_type, StructType}; pub fn message_impl( input: proc_macro::TokenStream, @@ -34,7 +34,7 @@ pub fn message_impl( let relations_complete_method = get_relations_complete_method(&fields, &struct_type); let bit_length_method = get_bit_length_method(&fields, &struct_type); let write_method = get_write_method(&fields, &struct_type); - let create_builder_method = get_create_builder_method(&builder_name, &turbofish); + let builder_create_method = get_builder_create_method(&builder_name, &turbofish); let builder_new_method = get_builder_new_method(&typed_generics, &builder_name, &untyped_generics, &input.generics); let builder_read_method = get_builder_read_method(&struct_name, &fields, &struct_type, &turbofish); let is_fragment_method = get_is_fragment_method(is_fragment); @@ -66,7 +66,7 @@ pub fn message_impl( #is_fragment_method #is_request_method #bit_length_method - #create_builder_method + #builder_create_method #relations_waiting_method #relations_complete_method #write_method @@ -388,7 +388,7 @@ fn get_bit_length_method(fields: &[Field], struct_type: &StructType) -> TokenStr } } -pub fn get_create_builder_method(builder_name: &Ident, turbofish: &TokenStream) -> TokenStream { +pub fn get_builder_create_method(builder_name: &Ident, turbofish: &TokenStream) -> TokenStream { let builder_new = quote! { #builder_name #turbofish::new() @@ -476,55 +476,6 @@ fn get_field_name(field: &Field, index: usize, struct_type: &StructType) -> Memb } } -fn get_generics(input: &DeriveInput) -> (TokenStream, TokenStream, TokenStream) { - let generics = &input.generics; - if generics.lt_token.is_none() { - return (quote! {}, quote! {}, quote! {}); - } - - let (impl_generics, ty_generics, _) = generics.split_for_impl(); - let typed_generics = quote! { - #impl_generics - }; - let untyped_generics = quote! { - #ty_generics - }; - let tf_generics = ty_generics.as_turbofish(); - let turbofish = quote! { - #tf_generics - }; - (untyped_generics, typed_generics, turbofish) -} - -fn get_builder_generic_fields(generics: &Generics) -> TokenStream { - if generics.gt_token.is_none() { - return quote! { ; }; - } - - let mut output = quote! {}; - - for param in generics.params.iter() { - let GenericParam::Type(type_param) = param else { - panic!("Only type parameters are supported for now"); - }; - - let uppercase_letter = &type_param.ident; - let field_name = format_ident!("phantom_{}", type_param.ident.to_string().to_lowercase()); - let new_output_right = quote! { - #field_name: std::marker::PhantomData<#uppercase_letter>, - }; - let new_output_result = quote! { - #output - #new_output_right - }; - output = new_output_result; - } - - quote! { - { #output } - } -} - pub fn get_builder_new_method( typed_generics: &TokenStream, builder_name: &Ident, diff --git a/shared/derive/src/replicate.rs b/shared/derive/src/replicate.rs index b629235c2..a8b40075e 100644 --- a/shared/derive/src/replicate.rs +++ b/shared/derive/src/replicate.rs @@ -5,7 +5,7 @@ use syn::{ PathArguments, Type, }; -use crate::shared::{get_struct_type, StructType}; +use crate::{message::get_builder_new_method, shared::{get_struct_type, StructType, get_generics, get_builder_generic_fields}}; const UNNAMED_FIELD_PREFIX: &'static str = "unnamed_field_"; @@ -43,10 +43,11 @@ pub fn replicate_impl( // Helper Properties let properties = get_properties(&input); let struct_type = get_struct_type(&input); + let (untyped_generics, typed_generics, turbofish) = get_generics(&input); // Names let replica_name = input.ident.clone(); - let replica_name_str = LitStr::new(&replica_name.to_string(), replica_name.span()); + let replica_name_str = LitStr::new(format!("{}{}", &replica_name.to_string(), &untyped_generics.to_string()).as_str(), replica_name.span()); let lowercase_replica_name = Ident::new( replica_name.to_string().to_lowercase().as_str(), Span::call_site(), @@ -54,29 +55,31 @@ pub fn replicate_impl( let module_name = format_ident!("define_{}", lowercase_replica_name); let enum_name = format_ident!("{}Property", replica_name); let builder_name = format_ident!("{}Builder", replica_name); + let builder_generic_fields = get_builder_generic_fields(&input.generics); // Definitions let property_enum_definition = get_property_enum_definition(&enum_name, &properties); - let diff_mask_size = { + let diff_mask_size: u8 = { let len = properties.len(); if len == 0 { - 0 + 0_u8 } else { - ((len - 1) / 8) + 1 + (((len - 1) / 8) + 1) as u8 } - } as u8; + }; // Methods let new_complete_method = - get_new_complete_method(&replica_name, &enum_name, &properties, &struct_type); - let create_builder_method = get_create_builder_method(&builder_name); - let read_method = get_read_method(&replica_name, &properties, &struct_type); - let read_create_update_method = get_read_create_update_method(&replica_name, &properties); + get_new_complete_method(&enum_name, &properties, &struct_type); + let builder_create_method = get_builder_create_method(&builder_name, &turbofish); + let builder_new_method = get_builder_new_method(&typed_generics, &builder_name, &untyped_generics, &input.generics); + let builder_read_method = get_builder_read_method(&replica_name, &properties, &struct_type, &turbofish); + let read_create_update_method = get_read_create_update_method(&replica_name, &properties, &untyped_generics); let dyn_ref_method = get_dyn_ref_method(); let dyn_mut_method = get_dyn_mut_method(); - let clone_method = get_clone_method(&replica_name, &properties, &struct_type); - let mirror_method = get_mirror_method(&replica_name, &properties, &struct_type); + let clone_method = get_clone_method(&properties, &struct_type); + let mirror_method = get_mirror_method(&replica_name, &properties, &struct_type, &untyped_generics); let set_mutator_method = get_set_mutator_method(&properties, &struct_type); let publish_method = get_publish_method(&enum_name, &properties, &struct_type); let unpublish_method = get_unpublish_method(&properties, &struct_type); @@ -91,7 +94,7 @@ pub fn replicate_impl( let write_update_method = get_write_update_method(&enum_name, &properties, &struct_type); let relations_waiting_method = get_relations_waiting_method(&properties, &struct_type); let relations_complete_method = get_relations_complete_method(&properties, &struct_type); - let split_update_method = get_split_update_method(&replica_name, &properties); + let split_update_method = get_split_update_method(&replica_name, &properties, &untyped_generics); let gen = quote! { mod #module_name { @@ -107,29 +110,30 @@ pub fn replicate_impl( #property_enum_definition - struct #builder_name; - impl ReplicateBuilder for #builder_name { - #read_method + struct #builder_name #typed_generics #builder_generic_fields + #builder_new_method + impl #typed_generics ReplicateBuilder for #builder_name #untyped_generics { + #builder_read_method #read_create_update_method #split_update_method } - impl Named for #builder_name { + impl #typed_generics Named for #builder_name #untyped_generics { fn name(&self) -> String { return #replica_name_str.to_string(); } } - impl #replica_name { + impl #typed_generics #replica_name #untyped_generics { #new_complete_method } - impl Named for #replica_name { + impl #typed_generics Named for #replica_name #untyped_generics { fn name(&self) -> String { return #replica_name_str.to_string(); } } - impl Replicate for #replica_name { + impl #typed_generics Replicate for #replica_name #untyped_generics { fn kind(&self) -> ComponentKind { - ComponentKind::of::<#replica_name>() + ComponentKind::of::<#replica_name #untyped_generics>() } fn to_any(&self) -> &dyn Any { self @@ -144,7 +148,7 @@ pub fn replicate_impl( Box::new(self.clone()) } fn diff_mask_size(&self) -> u8 { #diff_mask_size } - #create_builder_method + #builder_create_method #dyn_ref_method #dyn_mut_method #mirror_method @@ -161,7 +165,7 @@ pub fn replicate_impl( #relations_waiting_method #relations_complete_method } - impl Clone for #replica_name { + impl #typed_generics Clone for #replica_name #untyped_generics { #clone_method } } @@ -388,7 +392,6 @@ pub fn get_dyn_mut_method() -> TokenStream { } fn get_clone_method( - replica_name: &Ident, properties: &[Property], struct_type: &StructType, ) -> TokenStream { @@ -432,8 +435,8 @@ fn get_clone_method( } quote! { - fn clone(&self) -> #replica_name { - let mut new_clone = #replica_name::new_complete(#output); + fn clone(&self) -> Self { + let mut new_clone = Self::new_complete(#output); #entity_property_output return new_clone; } @@ -444,6 +447,7 @@ fn get_mirror_method( replica_name: &Ident, properties: &[Property], struct_type: &StructType, + untyped_generics: &TokenStream, ) -> TokenStream { let mut output = quote! {}; @@ -461,7 +465,7 @@ fn get_mirror_method( quote! { fn mirror(&mut self, other: &dyn Replicate) { - if let Some(replica) = other.to_any().downcast_ref::<#replica_name>() { + if let Some(replica) = other.to_any().downcast_ref::<#replica_name #untyped_generics>() { #output } else { panic!("cannot mirror: other Component is of another type!"); @@ -613,7 +617,6 @@ fn get_localize_method(properties: &[Property], struct_type: &StructType) -> Tok } pub fn get_new_complete_method( - replica_name: &Ident, enum_name: &Ident, properties: &[Property], struct_type: &StructType, @@ -727,44 +730,50 @@ pub fn get_new_complete_method( let fn_inner = match *struct_type { StructType::Struct => { quote! { - #replica_name { + Self { #fields } } } StructType::TupleStruct => { quote! { - #replica_name ( + Self ( #fields ) } } StructType::UnitStruct => { quote! { - #replica_name + Self } } }; quote! { - pub fn new_complete(#args) -> #replica_name { + pub fn new_complete(#args) -> Self { #fn_inner } } } -pub fn get_create_builder_method(builder_name: &Ident) -> TokenStream { +pub fn get_builder_create_method(builder_name: &Ident, turbofish: &TokenStream) -> TokenStream { + + let builder_new = quote! { + #builder_name #turbofish::new() + }; + quote! { fn create_builder() -> Box where Self:Sized { - Box::new(#builder_name) + Box::new(#builder_new) } } } -pub fn get_read_method( +pub fn get_builder_read_method( replica_name: &Ident, properties: &[Property], struct_type: &StructType, + turbofish: &TokenStream, ) -> TokenStream { let mut prop_names = quote! {}; for property in properties.iter() { @@ -813,14 +822,14 @@ pub fn get_read_method( let replica_build = match *struct_type { StructType::Struct => { quote! { - #replica_name { + #replica_name #turbofish { #prop_names } } } StructType::TupleStruct => { quote! { - #replica_name ( + #replica_name #turbofish ( #prop_names ) } @@ -841,7 +850,7 @@ pub fn get_read_method( } } -pub fn get_read_create_update_method(replica_name: &Ident, properties: &[Property]) -> TokenStream { +pub fn get_read_create_update_method(replica_name: &Ident, properties: &[Property], untyped_generics: &TokenStream) -> TokenStream { let mut prop_read_writes = quote! {}; for property in properties.iter() { let new_output_right = match property { @@ -889,12 +898,12 @@ pub fn get_read_create_update_method(replica_name: &Ident, properties: &[Propert let owned_reader = update_writer.to_owned_reader(); - return Ok(ComponentUpdate::new(ComponentKind::of::<#replica_name>(), owned_reader)); + return Ok(ComponentUpdate::new(ComponentKind::of::<#replica_name #untyped_generics>(), owned_reader)); } } } -fn get_split_update_method(replica_name: &Ident, properties: &[Property]) -> TokenStream { +fn get_split_update_method(replica_name: &Ident, properties: &[Property], untyped_generics: &TokenStream) -> TokenStream { let mut output = quote! {}; for property in properties.iter() { @@ -961,7 +970,7 @@ fn get_split_update_method(replica_name: &Ident, properties: &[Property]) -> Tok Option>, Option ), SerdeErr> { - let component_kind = ComponentKind::of::<#replica_name>(); + let component_kind = ComponentKind::of::<#replica_name #untyped_generics>(); let reader = &mut update.reader(); let mut waiting_did_write = false; diff --git a/shared/derive/src/shared.rs b/shared/derive/src/shared.rs index 98bd137ba..b0c62d678 100644 --- a/shared/derive/src/shared.rs +++ b/shared/derive/src/shared.rs @@ -1,4 +1,6 @@ -use syn::{Data, DeriveInput, Fields}; +use proc_macro2::TokenStream; +use quote::{format_ident, quote}; +use syn::{Data, DeriveInput, Fields, GenericParam, Generics}; pub enum StructType { Struct, @@ -17,3 +19,52 @@ pub(crate) fn get_struct_type(input: &DeriveInput) -> StructType { } panic!("Can only derive on a struct") } + +pub fn get_generics(input: &DeriveInput) -> (TokenStream, TokenStream, TokenStream) { + let generics = &input.generics; + if generics.lt_token.is_none() { + return (quote! {}, quote! {}, quote! {}); + } + + let (impl_generics, ty_generics, _) = generics.split_for_impl(); + let typed_generics = quote! { + #impl_generics + }; + let untyped_generics = quote! { + #ty_generics + }; + let tf_generics = ty_generics.as_turbofish(); + let turbofish = quote! { + #tf_generics + }; + (untyped_generics, typed_generics, turbofish) +} + +pub fn get_builder_generic_fields(generics: &Generics) -> TokenStream { + if generics.gt_token.is_none() { + return quote! { ; }; + } + + let mut output = quote! {}; + + for param in generics.params.iter() { + let GenericParam::Type(type_param) = param else { + panic!("Only type parameters are supported for now"); + }; + + let uppercase_letter = &type_param.ident; + let field_name = format_ident!("phantom_{}", type_param.ident.to_string().to_lowercase()); + let new_output_right = quote! { + #field_name: std::marker::PhantomData<#uppercase_letter>, + }; + let new_output_result = quote! { + #output + #new_output_right + }; + output = new_output_result; + } + + quote! { + { #output } + } +} \ No newline at end of file diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index 364920d93..c8b6ec26f 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -1,11 +1,10 @@ use std::{collections::HashMap, hash::Hash}; -use log::info; - use naia_serde::{BitReader, BitWrite, BitWriter, ConstBitLength, Serde, SerdeErr}; use naia_socket_shared::Instant; use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, messages::{ + request::GlobalRequestId, channels::{ channel::ChannelMode, channel::ChannelSettings, @@ -19,6 +18,7 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, unordered_unreliable_receiver::UnorderedUnreliableReceiver, }, senders::{ + request_sender::LocalResponseId, channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, reliable_message_sender::ReliableMessageSender, sequenced_unreliable_sender::SequencedUnreliableSender, @@ -30,8 +30,6 @@ use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, remote::entity_waitlist::EntityWaitlist, }}; -use crate::messages::channels::senders::request_sender::LocalResponseId; -use crate::messages::request::GlobalRequestId; /// Handles incoming/outgoing messages, tracks the delivery status of Messages /// so that guaranteed Messages can be re-transmitted to the remote host From 66b3809330e2ac13e59a11a3e3e95990d041b4ec Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Wed, 7 Feb 2024 22:13:48 -0600 Subject: [PATCH 33/99] test out components with non-marker generic type --- demos/basic/server/src/app.rs | 2 +- demos/basic/shared/src/protocol/character.rs | 10 +++++----- demos/basic/shared/src/protocol/mod.rs | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/demos/basic/server/src/app.rs b/demos/basic/server/src/app.rs index 4c0ae793b..896ba6fdd 100644 --- a/demos/basic/server/src/app.rs +++ b/demos/basic/server/src/app.rs @@ -59,7 +59,7 @@ impl App { count += 1; // Create a Character - let character = Character::::new((count * 4) as u8, 0, first, last); + let character = Character::::new(MyMarker, (count * 4) as u8, 0, first, last); let character_key = server .spawn_entity(world.proxy_mut()) .insert_component(character) diff --git a/demos/basic/shared/src/protocol/character.rs b/demos/basic/shared/src/protocol/character.rs index ba84ab183..8a123ef6d 100644 --- a/demos/basic/shared/src/protocol/character.rs +++ b/demos/basic/shared/src/protocol/character.rs @@ -11,17 +11,17 @@ pub struct FullName { } #[derive(Replicate)] -pub struct Character { - phantom_t: std::marker::PhantomData, +pub struct Character { + pub something: Property, pub x: Property, pub y: Property, pub fullname: Property, } -impl Character { - pub fn new(x: u8, y: u8, first: &str, last: &str) -> Self { +impl Character { + pub fn new(t: T, x: u8, y: u8, first: &str, last: &str) -> Self { Self::new_complete( - std::marker::PhantomData, + t, x, y, FullName { diff --git a/demos/basic/shared/src/protocol/mod.rs b/demos/basic/shared/src/protocol/mod.rs index 567007351..803b99527 100644 --- a/demos/basic/shared/src/protocol/mod.rs +++ b/demos/basic/shared/src/protocol/mod.rs @@ -12,7 +12,7 @@ pub use character::Character; pub use string_message::StringMessage; pub use basic_request::{BasicRequest, BasicResponse}; -#[derive(Serde, PartialEq, Clone)] +#[derive(Serde, PartialEq, Clone, Default)] pub struct MyMarker; // Protocol Build From 31953b0f8b7d5495e4b99b483ef1278d93b07dd6 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 13 Feb 2024 14:15:24 -0600 Subject: [PATCH 34/99] remove unused part of bevy demo --- demos/bevy/server/src/systems/events.rs | 20 -------------------- server/src/server.rs | 2 +- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/demos/bevy/server/src/systems/events.rs b/demos/bevy/server/src/systems/events.rs index 32090bcad..a13632ca4 100644 --- a/demos/bevy/server/src/systems/events.rs +++ b/demos/bevy/server/src/systems/events.rs @@ -88,26 +88,6 @@ pub fn connect_events( user_key, &assignment_message, ); - - // Create a new delegated Entity - info!("Spawn Delegated Entity on Connect"); - let delegated_entity = commands - // Spawn new Entity - .spawn_empty() - // MUST call this to begin replication - .enable_replication(&mut server) - .configure_replication(ReplicationConfig::Delegated) - // Insert Position component - .insert(Position::new( - 16 * ((Random::gen_range_u32(0, 40) as i16) - 20), - 16 * ((Random::gen_range_u32(0, 30) as i16) - 15), - )) - // return Entity id - .id(); - // Add to room - server - .room_mut(&global.main_room_key) - .add_entity(&delegated_entity); } } diff --git a/server/src/server.rs b/server/src/server.rs index 18c439df3..66b3c00ff 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -1258,7 +1258,7 @@ impl Server { panic!("entity should have an owner at this point"); }; let EntityOwner::ClientPublic(user_key) = entity_owner else { - panic!("entity should be owned by a public client at this point"); + panic!("entity should be owned by a public client at this point. Owner is: {:?}", entity_owner); }; self.global_world_manager.migrate_entity_to_server(&entity); From 60a1993698b5742c74978cff661aaa3268970cad Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 13 Feb 2024 19:12:05 -0600 Subject: [PATCH 35/99] added server.user_scope(user_key).has(entity) --- adapters/bevy/server/src/server.rs | 8 +++++-- demos/basic/server/src/app.rs | 12 ++++++---- demos/bevy/server/src/systems/events.rs | 8 ++++--- server/src/lib.rs | 2 +- server/src/server.rs | 31 +++++++++++++++++++++---- server/src/user_scope.rs | 23 +++++++++++++++++- 6 files changed, 68 insertions(+), 16 deletions(-) diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index 61d3308f9..adb612fa2 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -5,7 +5,7 @@ use bevy_ecs::{ system::{ResMut, SystemParam, Resource}, }; -use naia_server::{shared::SocketConfig, transport::Socket, ReplicationConfig, RoomKey, RoomMut, RoomRef, Server as NaiaServer, TickBufferMessages, UserKey, UserMut, UserRef, UserScopeMut, NaiaServerError}; +use naia_server::{shared::SocketConfig, transport::Socket, ReplicationConfig, RoomKey, RoomMut, RoomRef, Server as NaiaServer, TickBufferMessages, UserKey, UserMut, UserRef, UserScopeMut, NaiaServerError, UserScopeRef}; use naia_bevy_shared::{Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick}; @@ -101,10 +101,14 @@ impl<'w> Server<'w> { self.server.0.users_count() } - pub fn user_scope(&mut self, user_key: &UserKey) -> UserScopeMut { + pub fn user_scope(&self, user_key: &UserKey) -> UserScopeRef { self.server.0.user_scope(user_key) } + pub fn user_scope_mut(&mut self, user_key: &UserKey) -> UserScopeMut { + self.server.0.user_scope_mut(user_key) + } + //// Rooms //// pub fn make_room(&mut self) -> RoomMut { diff --git a/demos/basic/server/src/app.rs b/demos/basic/server/src/app.rs index 896ba6fdd..eda1007ac 100644 --- a/demos/basic/server/src/app.rs +++ b/demos/basic/server/src/app.rs @@ -153,10 +153,14 @@ impl App { for (_, user_key, entity) in server.scope_checks() { if let Some(character) = world.proxy().component::>(&entity) { let x = *character.x; - if (5..=15).contains(&x) { - server.user_scope(&user_key).include(&entity); - } else { - server.user_scope(&user_key).exclude(&entity); + let should_be_in_scope = (5..=15).contains(&x); + let is_in_scope = server.user_scope(&user_key).has(&entity); + if should_be_in_scope != is_in_scope { + if should_be_in_scope { + server.user_scope_mut(&user_key).include(&entity); + } else { + server.user_scope_mut(&user_key).exclude(&entity); + } } } } diff --git a/demos/bevy/server/src/systems/events.rs b/demos/bevy/server/src/systems/events.rs index a13632ca4..1938d0310 100644 --- a/demos/bevy/server/src/systems/events.rs +++ b/demos/bevy/server/src/systems/events.rs @@ -159,11 +159,13 @@ pub fn tick_events( // You'd normally do whatever checks you need to in here.. // to determine whether each Entity should be in scope or not. - // This indicates the Entity should be in this scope. - server.user_scope(&user_key).include(&entity); + if !server.user_scope(&user_key).has(&entity) { + // This indicates the Entity should be in this scope. + server.user_scope_mut(&user_key).include(&entity); + } // And call this if Entity should NOT be in this scope. - // server.user_scope(..).exclude(..); + // server.user_scope_mut(..).exclude(..); } } } diff --git a/server/src/lib.rs b/server/src/lib.rs index 248cf7f33..3343eb64d 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -52,7 +52,7 @@ pub use room::{RoomKey, RoomMut, RoomRef}; pub use server::Server; pub use server_config::ServerConfig; pub use user::{User, UserKey, UserMut, UserRef}; -pub use user_scope::UserScopeMut; +pub use user_scope::{UserScopeMut, UserScopeRef}; pub use world::{ entity_mut::EntityMut, entity_owner::EntityOwner, replication_config::ReplicationConfig, }; diff --git a/server/src/server.rs b/server/src/server.rs index 66b3c00ff..b7869d41e 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -26,16 +26,15 @@ use crate::{ server_auth_handler::AuthOwner, }, ReplicationConfig, + request::{GlobalRequestManager, GlobalResponseManager}, }; -use crate::request::{GlobalRequestManager, GlobalResponseManager}; - use super::{ error::NaiaServerError, events::Events, room::{Room, RoomKey, RoomMut, RoomRef}, server_config::ServerConfig, user::{User, UserKey, UserMut, UserRef}, - user_scope::UserScopeMut, + user_scope::{UserScopeRef, UserScopeMut}, }; /// A server that uses either UDP or WebRTC communication to send/receive @@ -82,7 +81,7 @@ impl Server { &protocol.compression, ); - Server { + Self { // Config server_config: server_config.clone(), protocol, @@ -845,9 +844,17 @@ impl Server { self.users.len() } + /// Returns a UserScopeRef, which is used to query whether a given user has + pub fn user_scope(&self, user_key: &UserKey) -> UserScopeRef { + if self.users.contains_key(user_key) { + return UserScopeRef::new(self, user_key); + } + panic!("No User exists for given Key!"); + } + /// Returns a UserScopeMut, which is used to include/exclude Entities for a /// given User - pub fn user_scope(&mut self, user_key: &UserKey) -> UserScopeMut { + pub fn user_scope_mut(&mut self, user_key: &UserKey) -> UserScopeMut { if self.users.contains_key(user_key) { return UserScopeMut::new(self, user_key); } @@ -1030,6 +1037,20 @@ impl Server { .insert(*user_key, *entity, is_contained); } + pub(crate) fn user_scope_has_entity( + &self, + user_key: &UserKey, + entity: &E, + ) -> bool { + if let Some(in_scope) = + self.entity_scope_map.get(user_key, entity) + { + *in_scope + } else { + false + } + } + //// Components /// Adds a Component to an Entity diff --git a/server/src/user_scope.rs b/server/src/user_scope.rs index cbdc09525..9caf3ba57 100644 --- a/server/src/user_scope.rs +++ b/server/src/user_scope.rs @@ -2,6 +2,22 @@ use std::hash::Hash; use super::{server::Server, user::UserKey}; +pub struct UserScopeRef<'s, E: Copy + Eq + Hash + Send + Sync> { + server: &'s Server, + key: UserKey, +} + +impl<'s, E: Copy + Eq + Hash + Send + Sync> UserScopeRef<'s, E> { + pub fn new(server: &'s Server, key: &UserKey) -> Self { + Self { server, key: *key } + } + + /// Returns true if the User's scope contains the Entity + pub fn has(&self, entity: &E) -> bool { + self.server.user_scope_has_entity(&self.key, entity) + } +} + pub struct UserScopeMut<'s, E: Copy + Eq + Hash + Send + Sync> { server: &'s mut Server, key: UserKey, @@ -9,7 +25,12 @@ pub struct UserScopeMut<'s, E: Copy + Eq + Hash + Send + Sync> { impl<'s, E: Copy + Eq + Hash + Send + Sync> UserScopeMut<'s, E> { pub fn new(server: &'s mut Server, key: &UserKey) -> Self { - UserScopeMut { server, key: *key } + Self { server, key: *key } + } + + /// Returns true if the User's scope contains the Entity + pub fn has(&self, entity: &E) -> bool { + self.server.user_scope_has_entity(&self.key, entity) } /// Adds an Entity to the User's scope From 0eda571d79f702d862e9264dbe393f826e48614a Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 13 Feb 2024 19:33:03 -0600 Subject: [PATCH 36/99] entities can be in multiple rooms at a time again .. I'm not sure how this may work with entity scope map stuff --- server/src/room.rs | 4 +++ server/src/server.rs | 26 +++++++------- server/src/world/entity_room_map.rs | 55 +++++++++++++++++++++++++++++ server/src/world/mod.rs | 1 + 4 files changed, 73 insertions(+), 13 deletions(-) create mode 100644 server/src/world/entity_room_map.rs diff --git a/server/src/room.rs b/server/src/room.rs index 21c8a384f..b576e7e5b 100644 --- a/server/src/room.rs +++ b/server/src/room.rs @@ -81,6 +81,10 @@ impl Room { } } + pub(crate) fn has_entity(&self, entity: &E) -> bool { + self.entities.contains(entity) + } + pub(crate) fn entities(&self) -> Iter { self.entities.iter() } diff --git a/server/src/server.rs b/server/src/server.rs index b7869d41e..19786b135 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -28,6 +28,7 @@ use crate::{ ReplicationConfig, request::{GlobalRequestManager, GlobalResponseManager}, }; +use crate::world::entity_room_map::EntityRoomMap; use super::{ error::NaiaServerError, events::Events, @@ -56,7 +57,7 @@ pub struct Server { // Rooms rooms: BigMap>, // Entities - entity_room_map: HashMap, + entity_room_map: EntityRoomMap, entity_scope_map: EntityScopeMap, global_world_manager: GlobalWorldManager, // Events @@ -98,7 +99,7 @@ impl Server { // Rooms rooms: BigMap::new(), // Entities - entity_room_map: HashMap::new(), + entity_room_map: EntityRoomMap::new(), entity_scope_map: EntityScopeMap::new(), global_world_manager: GlobalWorldManager::new(), // Events @@ -998,9 +999,11 @@ impl Server { self.entity_scope_map.remove_entity(entity); // Delete room cache entry - if let Some(room_key) = self.entity_room_map.remove(entity) { - if let Some(room) = self.rooms.get_mut(&room_key) { - room.remove_entity(entity, true); + if let Some(room_keys) = self.entity_room_map.remove_from_all_rooms(entity) { + for room_key in room_keys { + if let Some(room) = self.rooms.get_mut(&room_key) { + room.remove_entity(entity, true); + } } } @@ -1553,10 +1556,10 @@ impl Server { /// Returns whether or not an Entity is currently in a specific Room, given /// their keys. pub(crate) fn room_has_entity(&self, room_key: &RoomKey, entity: &E) -> bool { - let Some(actual_room_key) = self.entity_room_map.get(entity) else { + let Some(room) = self.rooms.get(room_key) else { return false; }; - return *room_key == *actual_room_key; + return room.has_entity(entity); } /// Add an Entity to a Room associated with the given RoomKey. @@ -1571,17 +1574,14 @@ impl Server { if !is_some { return; } - if self.entity_room_map.contains_key(entity) { - panic!("Entity already belongs to a Room! Remove the Entity from the Room before adding it to a new Room."); - } - self.entity_room_map.insert(*entity, *room_key); + self.entity_room_map.entity_add_room(entity, room_key); } /// Remove an Entity from a Room, associated with the given RoomKey pub(crate) fn room_remove_entity(&mut self, room_key: &RoomKey, entity: &E) { if let Some(room) = self.rooms.get_mut(room_key) { room.remove_entity(entity, false); - self.entity_room_map.remove(entity); + self.entity_room_map.remove_from_room(entity, room_key); } } @@ -1591,7 +1591,7 @@ impl Server { let entities: Vec = room.entities().copied().collect(); for entity in entities { room.remove_entity(&entity, false); - self.entity_room_map.remove(&entity); + self.entity_room_map.remove_from_room(&entity, room_key); } } } diff --git a/server/src/world/entity_room_map.rs b/server/src/world/entity_room_map.rs new file mode 100644 index 000000000..309761ee3 --- /dev/null +++ b/server/src/world/entity_room_map.rs @@ -0,0 +1,55 @@ +use std::{ + collections::{HashMap, HashSet}, + hash::Hash, +}; + +use crate::RoomKey; + +pub struct EntityRoomMap { + map: HashMap> +} + +impl EntityRoomMap { + pub fn new() -> Self { + Self { + map: HashMap::new() + } + } + + pub(crate) fn entity_add_room(&mut self, entity: &E, room_key: &RoomKey) { + if !self.map.contains_key(entity) { + self.map.insert(*entity, HashSet::new()); + } + let rooms = self.map.get_mut(entity).unwrap(); + rooms.insert(*room_key); + } + + pub(crate) fn remove_from_room(&mut self, entity: &E, room_key: &RoomKey) { + let mut delete = false; + if let Some(rooms) = self.map.get_mut(entity) { + rooms.remove(room_key); + if rooms.is_empty() { + delete = true; + } + } + if delete { + self.map.remove(entity); + } + } + + pub(crate) fn remove_from_all_rooms(&mut self, entity: &E) -> Option> { + let mut output = Vec::new(); + + if let Some(rooms) = self.map.remove(entity) { + for room in rooms { + output.push(room); + } + } + + if output.is_empty() { + None + } else { + Some(output) + } + } +} diff --git a/server/src/world/mod.rs b/server/src/world/mod.rs index 659df5ff2..f3d5f0a58 100644 --- a/server/src/world/mod.rs +++ b/server/src/world/mod.rs @@ -7,3 +7,4 @@ pub mod global_world_manager; pub mod mut_channel; pub mod replication_config; pub mod server_auth_handler; +pub mod entity_room_map; From 67ccbba7e172d577b3fc24659bf166a2548d23ac Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 18 Feb 2024 14:25:12 -0600 Subject: [PATCH 37/99] updating to bevy 0.13 --- adapters/bevy/client/Cargo.toml | 4 +-- adapters/bevy/server/Cargo.toml | 4 +-- adapters/bevy/server/src/commands.rs | 34 +++++++++++----------- adapters/bevy/server/src/systems.rs | 6 ++-- adapters/bevy/shared/Cargo.toml | 4 +-- demos/bevy/client/Cargo.toml | 2 +- demos/bevy/server/Cargo.toml | 8 ++--- demos/bevy/shared/Cargo.toml | 2 +- server/src/connection/handshake_manager.rs | 6 ++-- shared/Cargo.toml | 2 +- socket/server/src/socket.rs | 1 + 11 files changed, 37 insertions(+), 36 deletions(-) diff --git a/adapters/bevy/client/Cargo.toml b/adapters/bevy/client/Cargo.toml index 949385215..192479c5b 100644 --- a/adapters/bevy/client/Cargo.toml +++ b/adapters/bevy/client/Cargo.toml @@ -19,6 +19,6 @@ transport_udp = [ "naia-client/transport_udp" ] [dependencies] naia-client = { version = "0.22", path = "../../../client", features = ["bevy_support", "wbindgen"] } naia-bevy-shared = { version = "0.22", path = "../shared" } -bevy_app = { version = "0.12.1", default-features=false } -bevy_ecs = { version = "0.12.1", default-features=false } +bevy_app = { version = "0.13", default-features=false } +bevy_ecs = { version = "0.13", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/bevy/server/Cargo.toml b/adapters/bevy/server/Cargo.toml index f134d2ff1..b9cb47a44 100644 --- a/adapters/bevy/server/Cargo.toml +++ b/adapters/bevy/server/Cargo.toml @@ -19,6 +19,6 @@ transport_udp = [ "naia-server/transport_udp" ] [dependencies] naia-server = { version = "0.22", path = "../../../server", features = ["bevy_support"] } naia-bevy-shared = { version = "0.22", path = "../shared" } -bevy_app = { version = "0.12.1", default-features=false } -bevy_ecs = { version = "0.12.1", default-features=false } +bevy_app = { version = "0.13", default-features=false } +bevy_ecs = { version = "0.13", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/bevy/server/src/commands.rs b/adapters/bevy/server/src/commands.rs index 1b2f3e5fd..b4b8d790d 100644 --- a/adapters/bevy/server/src/commands.rs +++ b/adapters/bevy/server/src/commands.rs @@ -11,28 +11,28 @@ use crate::plugin::Singleton; use crate::{server::ServerWrapper, Server}; // Bevy Commands Extension -pub trait CommandsExt<'w, 's, 'a> { - fn enable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a>; +pub trait CommandsExt<'a> { + fn enable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a>; fn disable_replication(&'a mut self, server: &mut Server) - -> &'a mut EntityCommands<'w, 's, 'a>; + -> &'a mut EntityCommands<'a>; fn configure_replication( &'a mut self, config: ReplicationConfig, - ) -> &'a mut EntityCommands<'w, 's, 'a>; + ) -> &'a mut EntityCommands<'a>; fn replication_config(&'a self, server: &Server) -> Option; fn give_authority( &'a mut self, server: &mut Server, user_key: &UserKey, - ) -> &'a mut EntityCommands<'w, 's, 'a>; - fn take_authority(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a>; + ) -> &'a mut EntityCommands<'a>; + fn take_authority(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a>; fn authority(&'a self, server: &Server) -> Option; - fn pause_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a>; - fn resume_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a>; + fn pause_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a>; + fn resume_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a>; } -impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { - fn enable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a> { +impl<'a> CommandsExt<'a> for EntityCommands<'a> { + fn enable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a> { server.enable_replication(&self.id()); self.insert(HostOwned::new::()); return self; @@ -41,7 +41,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn disable_replication( &'a mut self, server: &mut Server, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { server.disable_replication(&self.id()); self.remove::(); return self; @@ -50,9 +50,9 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn configure_replication( &'a mut self, config: ReplicationConfig, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { let entity = self.id(); - let commands = self.commands(); + let mut commands = self.commands(); let command = ConfigureReplicationCommand::new(entity, config); commands.add(command); return self; @@ -66,11 +66,11 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { &'a mut self, _server: &mut Server, _user_key: &UserKey, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { todo!() } - fn take_authority(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a> { + fn take_authority(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a> { server.entity_take_authority(&self.id()); return self; } @@ -79,12 +79,12 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { server.entity_authority_status(&self.id()) } - fn pause_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a> { + fn pause_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a> { server.pause_replication(&self.id()); return self; } - fn resume_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'w, 's, 'a> { + fn resume_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a> { server.resume_replication(&self.id()); return self; } diff --git a/adapters/bevy/server/src/systems.rs b/adapters/bevy/server/src/systems.rs index 052a654d7..0df10f957 100644 --- a/adapters/bevy/server/src/systems.rs +++ b/adapters/bevy/server/src/systems.rs @@ -14,9 +14,9 @@ use crate::{plugin::Singleton, server::ServerWrapper, ClientOwned, EntityAuthSta mod naia_events { pub use naia_server::{ ConnectEvent, DelegateEntityEvent, DespawnEntityEvent, DisconnectEvent, - EntityAuthGrantEvent, EntityAuthResetEvent, ErrorEvent, InsertComponentEvent, - PublishEntityEvent, RemoveComponentEvent, SpawnEntityEvent, TickEvent, - UnpublishEntityEvent, UpdateComponentEvent, + EntityAuthGrantEvent, EntityAuthResetEvent, ErrorEvent, + PublishEntityEvent, SpawnEntityEvent, TickEvent, + UnpublishEntityEvent, }; } diff --git a/adapters/bevy/shared/Cargo.toml b/adapters/bevy/shared/Cargo.toml index 776d553d7..0038d7041 100644 --- a/adapters/bevy/shared/Cargo.toml +++ b/adapters/bevy/shared/Cargo.toml @@ -16,6 +16,6 @@ maintenance = { status = "actively-developed" } [dependencies] naia-shared = { version = "0.22", path = "../../../shared", features = ["bevy_support", "wbindgen"] } -bevy_app = { version = "0.12.1", default-features=false } -bevy_ecs = { version = "0.12.1", default-features=false } +bevy_app = { version = "0.13", default-features=false } +bevy_ecs = { version = "0.13", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/demos/bevy/client/Cargo.toml b/demos/bevy/client/Cargo.toml index 18a84d450..b3850252e 100644 --- a/demos/bevy/client/Cargo.toml +++ b/demos/bevy/client/Cargo.toml @@ -22,7 +22,7 @@ crate-type = ["cdylib", "rlib"] naia-bevy-client = { path = "../../../adapters/bevy/client", features = ["transport_webrtc"] } naia-bevy-demo-shared = { path = "../shared" } -bevy = { version = "0.12.1", default_features = false, features = [ "bevy_asset", "bevy_winit", "bevy_core_pipeline", "bevy_render", "bevy_sprite", "x11", "webgl2"] } +bevy = { version = "0.13", default_features = false, features = [ "bevy_asset", "bevy_winit", "bevy_core_pipeline", "bevy_render", "bevy_sprite", "x11", "webgl2"] } cfg-if = { version = "1.0" } diff --git a/demos/bevy/server/Cargo.toml b/demos/bevy/server/Cargo.toml index 86dcd6240..5b7c8cb66 100644 --- a/demos/bevy/server/Cargo.toml +++ b/demos/bevy/server/Cargo.toml @@ -10,7 +10,7 @@ publish = false [dependencies] naia-bevy-demo-shared = { path = "../shared" } naia-bevy-server = { path = "../../../adapters/bevy/server", features = [ "transport_webrtc" ] } -bevy_app = { version = "0.12.1", default-features=false } -bevy_core = { version = "0.12.1", default-features=false } -bevy_ecs = { version = "0.12.1", default-features=false } -bevy_log = { version = "0.12.1", default-features=false } +bevy_app = { version = "0.13", default-features=false } +bevy_core = { version = "0.13", default-features=false } +bevy_ecs = { version = "0.13", default-features=false } +bevy_log = { version = "0.13", default-features=false } diff --git a/demos/bevy/shared/Cargo.toml b/demos/bevy/shared/Cargo.toml index 668035e4f..2e057cc47 100644 --- a/demos/bevy/shared/Cargo.toml +++ b/demos/bevy/shared/Cargo.toml @@ -11,6 +11,6 @@ publish = false [dependencies] naia-bevy-shared = { path = "../../../adapters/bevy/shared" } -bevy_ecs = { version = "0.12.1", default-features=false} +bevy_ecs = { version = "0.13", default-features=false} cfg-if = { version = "1.0" } log = { version = "0.4" } \ No newline at end of file diff --git a/server/src/connection/handshake_manager.rs b/server/src/connection/handshake_manager.rs index 65a4effcb..95df6472b 100644 --- a/server/src/connection/handshake_manager.rs +++ b/server/src/connection/handshake_manager.rs @@ -3,9 +3,9 @@ use std::{collections::HashMap, hash::Hash, net::SocketAddr}; use ring::{hmac, rand}; pub use naia_shared::{ - wrapping_diff, BaseConnection, BitReader, BitWriter, ConnectionConfig, FakeEntityConverter, - Instant, KeyGenerator, Message, MessageContainer, MessageKinds, PacketType, PropertyMutate, - PropertyMutator, Replicate, Serde, SerdeErr, StandardHeader, Timer, WorldMutType, WorldRefType, + BitReader, BitWriter, FakeEntityConverter, + MessageContainer, MessageKinds, PacketType, + Serde, SerdeErr, StandardHeader, }; use crate::{cache_map::CacheMap, connection::connection::Connection}; diff --git a/shared/Cargo.toml b/shared/Cargo.toml index ef8c2e2b3..53f6e7e1d 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -29,5 +29,5 @@ naia-serde = { version = "0.22", path = "serde" } log = { version = "0.4" } cfg-if = { version = "1.0" } js-sys = { version = "0.3", optional = true } -bevy_ecs = { version = "0.12.1", default_features = false, optional = true } +bevy_ecs = { version = "0.13", default_features = false, optional = true } zstd = { version = "0.12.2", optional = true } \ No newline at end of file diff --git a/socket/server/src/socket.rs b/socket/server/src/socket.rs index 0c57e67ec..71ae79c8e 100644 --- a/socket/server/src/socket.rs +++ b/socket/server/src/socket.rs @@ -14,6 +14,7 @@ use super::{ }; /// Used to send packets from the Server Socket +#[allow(dead_code)] pub trait SocketTrait { fn listen( server_addrs: &ServerAddrs, From 6f89cc9ea761f553e23150d5e288e5a27ac181b7 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 18 Feb 2024 15:09:30 -0600 Subject: [PATCH 38/99] update client demo to bevy 0.13 --- adapters/bevy/client/src/commands.rs | 34 ++++++++++++------------- demos/bevy/client/src/systems/events.rs | 6 ++--- demos/bevy/client/src/systems/init.rs | 4 +-- demos/bevy/client/src/systems/input.rs | 14 +++++----- socket/client/src/backends/socket.rs | 1 + 5 files changed, 30 insertions(+), 29 deletions(-) diff --git a/adapters/bevy/client/src/commands.rs b/adapters/bevy/client/src/commands.rs index 797abdf06..ed770dc11 100644 --- a/adapters/bevy/client/src/commands.rs +++ b/adapters/bevy/client/src/commands.rs @@ -12,20 +12,20 @@ use naia_client::ReplicationConfig; use crate::{client::ClientWrapper, Client}; // Bevy Commands Extension -pub trait CommandsExt<'w, 's, 'a> { - fn local_duplicate(&'a mut self) -> EntityCommands<'w, 's, 'a>; +pub trait CommandsExt<'a> { + fn local_duplicate(&'a mut self) -> Entity; fn configure_replication( &'a mut self, config: ReplicationConfig, - ) -> &'a mut EntityCommands<'w, 's, 'a>; + ) -> &'a mut EntityCommands<'a>; fn enable_replication( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a>; + ) -> &'a mut EntityCommands<'a>; fn disable_replication( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a>; + ) -> &'a mut EntityCommands<'a>; fn replication_config( &'a self, client: &Client, @@ -33,31 +33,31 @@ pub trait CommandsExt<'w, 's, 'a> { fn request_authority( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a>; + ) -> &'a mut EntityCommands<'a>; fn release_authority( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a>; + ) -> &'a mut EntityCommands<'a>; fn authority( &'a self, client: &Client, ) -> Option; } -impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { - fn local_duplicate(&'a mut self) -> EntityCommands<'w, 's, 'a> { +impl<'a> CommandsExt<'a> for EntityCommands<'a> { + fn local_duplicate(&'a mut self) -> Entity { let old_entity = self.id(); - let commands = self.commands(); + let mut commands = self.commands(); let new_entity = commands.spawn_empty().id(); let command = LocalDuplicateComponents::new(new_entity, old_entity); commands.add(command); - commands.entity(new_entity) + new_entity } fn enable_replication( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { client.enable_replication(&self.id()); self.insert(HostOwned::new::()); return self; @@ -66,7 +66,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn disable_replication( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { client.disable_replication(&self.id()); self.remove::(); return self; @@ -75,9 +75,9 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn configure_replication( &'a mut self, config: ReplicationConfig, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { let entity = self.id(); - let commands = self.commands(); + let mut commands = self.commands(); let command = ConfigureReplicationCommand::::new(entity, config); commands.add(command); return self; @@ -93,7 +93,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn request_authority( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { client.entity_request_authority(&self.id()); return self; } @@ -101,7 +101,7 @@ impl<'w, 's, 'a> CommandsExt<'w, 's, 'a> for EntityCommands<'w, 's, 'a> { fn release_authority( &'a mut self, client: &mut Client, - ) -> &'a mut EntityCommands<'w, 's, 'a> { + ) -> &'a mut EntityCommands<'a> { client.entity_release_authority(&self.id()); return self; } diff --git a/demos/bevy/client/src/systems/events.rs b/demos/bevy/client/src/systems/events.rs index fa84d37f9..14ded53d0 100644 --- a/demos/bevy/client/src/systems/events.rs +++ b/demos/bevy/client/src/systems/events.rs @@ -101,7 +101,8 @@ pub fn message_events( if let Ok(position) = position_query.get(entity) { let prediction_entity = commands .entity(entity) - .local_duplicate() // copies all Replicate components as well + .local_duplicate(); // copies all Replicate components as well + commands.entity(prediction_entity) .insert(SpriteBundle { sprite: Sprite { custom_size: Some(Vec2::new(SQUARE_SIZE, SQUARE_SIZE)), @@ -114,8 +115,7 @@ pub fn message_events( // insert interpolation component .insert(Interp::new(*position.x, *position.y)) // mark as predicted - .insert(Predicted) - .id(); + .insert(Predicted); global.owned_entity = Some(OwnedEntity::new(entity, prediction_entity)); } diff --git a/demos/bevy/client/src/systems/init.rs b/demos/bevy/client/src/systems/init.rs index aa757a98b..a9b1b63b3 100644 --- a/demos/bevy/client/src/systems/init.rs +++ b/demos/bevy/client/src/systems/init.rs @@ -1,6 +1,6 @@ use bevy::{prelude::{ - shape, Assets, Camera2dBundle, Color, ColorMaterial, Commands, Mesh, ResMut, + Assets, Camera2dBundle, Color, ColorMaterial, Commands, Mesh, ResMut, Circle, }, log::info}; use naia_bevy_client::{transport::webrtc, Client}; @@ -37,7 +37,7 @@ pub fn init( global.aqua = materials.add(ColorMaterial::from(Color::AQUAMARINE)); // Load shapes - global.circle = meshes.add(shape::Circle::new(6.).into()); + global.circle = meshes.add(Circle::new(6.)); // Insert Global Resource commands.insert_resource(global); diff --git a/demos/bevy/client/src/systems/input.rs b/demos/bevy/client/src/systems/input.rs index d2f7e5912..f9647db51 100644 --- a/demos/bevy/client/src/systems/input.rs +++ b/demos/bevy/client/src/systems/input.rs @@ -1,4 +1,4 @@ -use bevy::prelude::{Commands, Input, KeyCode, Query, Res, ResMut, Vec2, Window}; +use bevy::prelude::{ButtonInput, Commands, KeyCode, Query, Res, ResMut, Vec2, Window}; use naia_bevy_client::{Client, CommandsExt, ReplicationConfig}; use naia_bevy_demo_shared::{components::Position, messages::KeyCommand}; @@ -9,13 +9,13 @@ pub fn key_input( client: Client
, mut commands: Commands, mut global: ResMut, - keyboard_input: Res>, + keyboard_input: Res>, ) { - let w = keyboard_input.pressed(KeyCode::W); - let s = keyboard_input.pressed(KeyCode::S); - let a = keyboard_input.pressed(KeyCode::A); - let d = keyboard_input.pressed(KeyCode::D); - let x = keyboard_input.pressed(KeyCode::X); + let w = keyboard_input.pressed(KeyCode::KeyW); + let s = keyboard_input.pressed(KeyCode::KeyS); + let a = keyboard_input.pressed(KeyCode::KeyA); + let d = keyboard_input.pressed(KeyCode::KeyD); + let x = keyboard_input.pressed(KeyCode::KeyX); if let Some(command) = &mut global.queued_command { if w { diff --git a/socket/client/src/backends/socket.rs b/socket/client/src/backends/socket.rs index afd0623bc..9951f4391 100644 --- a/socket/client/src/backends/socket.rs +++ b/socket/client/src/backends/socket.rs @@ -3,6 +3,7 @@ use naia_socket_shared::SocketConfig; use crate::{packet_receiver::PacketReceiver, packet_sender::PacketSender}; /// Used to send packets from the Client Socket +#[allow(dead_code)] pub trait SocketTrait { fn connect( server_session_url: &str, From d64acc63247287dcc78dbd346d3264a97c9600e2 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 18 Feb 2024 21:03:17 -0600 Subject: [PATCH 39/99] updating wasm-bindgen, web-sys, js-sys dependencies --- demos/basic/client/wasm_bindgen/Cargo.toml | 4 ++-- demos/bevy/client/Cargo.toml | 2 +- demos/hecs/client/Cargo.toml | 4 ++-- demos/socket/client/wasm_bindgen/Cargo.toml | 4 ++-- shared/Cargo.toml | 2 +- socket/client/Cargo.toml | 6 +++--- socket/shared/Cargo.toml | 4 ++-- 7 files changed, 13 insertions(+), 13 deletions(-) diff --git a/demos/basic/client/wasm_bindgen/Cargo.toml b/demos/basic/client/wasm_bindgen/Cargo.toml index 5b39eac7d..88cf697d1 100644 --- a/demos/basic/client/wasm_bindgen/Cargo.toml +++ b/demos/basic/client/wasm_bindgen/Cargo.toml @@ -28,5 +28,5 @@ simple_logger = { version = "4.0", default-features = false, features = ["timest [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-logger = { version = "0.2" } -wasm-bindgen = { version = "0.2.84", features = [ "serde-serialize" ] } -web-sys = { version = "0.3", features = [ 'Window' ] } \ No newline at end of file +wasm-bindgen = { version = "0.2", features = [ "serde-serialize" ] } +web-sys = { version = "0.3.64", features = [ 'Window' ] } \ No newline at end of file diff --git a/demos/bevy/client/Cargo.toml b/demos/bevy/client/Cargo.toml index b3850252e..03c8eaa43 100644 --- a/demos/bevy/client/Cargo.toml +++ b/demos/bevy/client/Cargo.toml @@ -27,4 +27,4 @@ bevy = { version = "0.13", default_features = false, features = [ "bevy_asset", cfg-if = { version = "1.0" } [target.'cfg(target_arch = "wasm32")'.dependencies] -wasm-bindgen = { version = "0.2.84", features = [ "serde-serialize" ] } \ No newline at end of file +wasm-bindgen = { version = "0.2", features = [ "serde-serialize" ] } \ No newline at end of file diff --git a/demos/hecs/client/Cargo.toml b/demos/hecs/client/Cargo.toml index d472f5f31..28eea2b9a 100644 --- a/demos/hecs/client/Cargo.toml +++ b/demos/hecs/client/Cargo.toml @@ -30,5 +30,5 @@ simple_logger = { version = "4.0", default-features = false, features = ["timest [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-logger = { version = "0.2" } -wasm-bindgen = { version = "0.2.84", features = [ "serde-serialize" ] } -web-sys = { version = "0.3", features = [ 'Window' ] } \ No newline at end of file +wasm-bindgen = { version = "0.2", features = [ "serde-serialize" ] } +web-sys = { version = "0.3.64", features = [ 'Window' ] } \ No newline at end of file diff --git a/demos/socket/client/wasm_bindgen/Cargo.toml b/demos/socket/client/wasm_bindgen/Cargo.toml index aa68119e1..56a6b286a 100755 --- a/demos/socket/client/wasm_bindgen/Cargo.toml +++ b/demos/socket/client/wasm_bindgen/Cargo.toml @@ -28,5 +28,5 @@ simple_logger = { version = "4.0", default-features = false, features = ["timest [target.'cfg(target_arch = "wasm32")'.dependencies] wasm-logger = { version = "0.2" } -wasm-bindgen = { version = "0.2.84", features = [ "serde-serialize" ] } -web-sys = { version = "0.3", features = [ 'Window' ] } \ No newline at end of file +wasm-bindgen = { version = "0.2", features = [ "serde-serialize" ] } +web-sys = { version = "0.3.64", features = [ 'Window' ] } \ No newline at end of file diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 53f6e7e1d..fea005577 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -28,6 +28,6 @@ naia-derive = { version = "0.22", path = "derive" } naia-serde = { version = "0.22", path = "serde" } log = { version = "0.4" } cfg-if = { version = "1.0" } -js-sys = { version = "0.3", optional = true } +js-sys = { version = "0.3.64", optional = true } bevy_ecs = { version = "0.13", default_features = false, optional = true } zstd = { version = "0.12.2", optional = true } \ No newline at end of file diff --git a/socket/client/Cargo.toml b/socket/client/Cargo.toml index c70c8559b..7232369e3 100644 --- a/socket/client/Cargo.toml +++ b/socket/client/Cargo.toml @@ -23,9 +23,9 @@ mquad = [ "naia-socket-shared/mquad", "miniquad" ] naia-socket-shared = { version = "0.22", path = "../shared" } cfg-if = { version = "1.0" } log = { version = "0.4" } -wasm-bindgen = { version = "0.2.84", optional = true } -js-sys = { version = "0.3", optional = true } -web_sys = { version = "0.3", package = "web-sys", features = [ +wasm-bindgen = { version = "0.2", optional = true } +js-sys = { version = "0.3.64", optional = true } +web_sys = { version = "0.3.64", package = "web-sys", features = [ "RtcDataChannel", "RtcDataChannelInit", "RtcDataChannelType", "MessageChannel", "MessagePort", "RtcIceCandidate", "RtcIceCandidateInit", "RtcConfiguration", "RtcDataChannelState", "RtcPeerConnection", "RtcSdpType", "RtcSessionDescription", "RtcSessionDescriptionInit", diff --git a/socket/shared/Cargo.toml b/socket/shared/Cargo.toml index 5eca89baf..5efd4bbc0 100644 --- a/socket/shared/Cargo.toml +++ b/socket/shared/Cargo.toml @@ -23,8 +23,8 @@ mquad = [ ] cfg-if = { version = "1.0" } log = { version = "0.4" } url = { version = "2.2.2" } -wasm-bindgen = { version = "0.2.84", optional = true } -js-sys = { version = "0.3", optional = true } +wasm-bindgen = { version = "0.2", optional = true } +js-sys = { version = "0.3.64", optional = true } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] rand = { version = "0.8" } From febfacf19a870451981d001fc274aa4d1aa3f15e Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 19 Feb 2024 19:55:51 -0600 Subject: [PATCH 40/99] cargo fmt --- adapters/bevy/client/src/client.rs | 18 +++- adapters/bevy/client/src/events.rs | 5 +- adapters/bevy/client/src/plugin.rs | 2 +- adapters/bevy/client/src/systems.rs | 44 +++++---- adapters/bevy/server/src/commands.rs | 12 +-- adapters/bevy/server/src/events.rs | 25 +++-- adapters/bevy/server/src/lib.rs | 4 +- adapters/bevy/server/src/plugin.rs | 2 +- adapters/bevy/server/src/server.rs | 31 ++++-- adapters/bevy/server/src/systems.rs | 7 +- adapters/bevy/shared/src/lib.rs | 7 +- adapters/bevy/shared/src/protocol.rs | 5 +- client/src/client.rs | 43 +++++++-- client/src/connection/connection.rs | 26 +++-- client/src/connection/handshake_manager.rs | 8 +- client/src/events.rs | 5 +- client/src/lib.rs | 10 +- client/src/request.rs | 32 +++++-- client/src/world/global_world_manager.rs | 2 +- demos/basic/client/app/src/app.rs | 12 ++- demos/basic/server/src/app.rs | 12 ++- demos/basic/shared/src/lib.rs | 4 +- .../shared/src/protocol/basic_request.rs | 2 +- demos/basic/shared/src/protocol/character.rs | 1 - demos/basic/shared/src/protocol/mod.rs | 4 +- .../shared/src/protocol/string_message.rs | 6 +- demos/bevy/client/src/app.rs | 5 +- demos/bevy/client/src/systems/events.rs | 24 +++-- demos/bevy/client/src/systems/init.rs | 8 +- demos/bevy/client/src/systems/input.rs | 4 +- demos/bevy/client/src/systems/sync.rs | 5 +- demos/bevy/server/src/resources.rs | 2 +- demos/bevy/server/src/systems/events.rs | 50 ++++++---- .../bevy/shared/src/messages/basic_request.rs | 6 +- demos/bevy/shared/src/messages/mod.rs | 4 +- demos/demo_utils/demo_world/src/world.rs | 7 +- server/src/connection/connection.rs | 29 ++++-- server/src/connection/handshake_manager.rs | 5 +- server/src/events.rs | 15 ++- server/src/lib.rs | 11 ++- server/src/request.rs | 38 ++++++-- server/src/server.rs | 94 ++++++++++++------- server/src/world/entity_room_map.rs | 4 +- server/src/world/mod.rs | 2 +- shared/derive/src/message.rs | 30 ++++-- shared/derive/src/replicate.rs | 55 +++++++---- shared/derive/src/shared.rs | 2 +- shared/serde/src/impls.rs | 2 +- shared/serde/src/impls/phantom.rs | 4 +- shared/src/lib.rs | 20 ++-- .../channels/receivers/channel_receiver.rs | 13 ++- .../channels/receivers/fragment_receiver.rs | 1 - .../receivers/reliable_message_receiver.rs | 43 ++++++--- .../sequenced_unreliable_receiver.rs | 27 ++++-- .../unordered_unreliable_receiver.rs | 19 +++- .../channels/senders/channel_sender.rs | 27 +++++- shared/src/messages/channels/senders/mod.rs | 4 +- .../senders/reliable_message_sender.rs | 39 +++++--- .../channels/senders/reliable_sender.rs | 7 +- .../channels/senders/request_sender.rs | 24 +++-- .../senders/sequenced_unreliable_sender.rs | 36 +++++-- .../senders/unordered_unreliable_sender.rs | 30 ++++-- shared/src/messages/message_manager.rs | 89 +++++++++++------- shared/src/messages/mod.rs | 2 - shared/src/messages/request.rs | 13 +-- shared/src/messages/tests/fragment.rs | 10 +- shared/src/protocol.rs | 25 +++-- shared/src/types.rs | 2 +- shared/src/world/entity/entity_converters.rs | 3 +- shared/src/world/local_entity_map.rs | 4 +- .../src/world/remote/remote_world_manager.rs | 3 +- 71 files changed, 774 insertions(+), 402 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 5fb2c4dd6..248b16795 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -7,7 +7,7 @@ use bevy_ecs::{ use naia_bevy_shared::{ Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, - GlobalEntity, Message, Tick, Request, Response, ResponseReceiveKey, ResponseSendKey, + GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick, }; use naia_client::{ shared::SocketConfig, transport::Socket, Client as NaiaClient, ConnectionStatus, @@ -87,15 +87,25 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { } /// Requests /// - pub fn send_request(&mut self, request: &Q) -> Result, NaiaClientError> { + pub fn send_request( + &mut self, + request: &Q, + ) -> Result, NaiaClientError> { self.client.client.send_request::(request) } - pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { + pub fn send_response( + &mut self, + response_key: &ResponseSendKey, + response: &S, + ) -> bool { self.client.client.send_response(response_key, response) } - pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { + pub fn receive_response( + &mut self, + response_key: &ResponseReceiveKey, + ) -> Option { self.client.client.receive_response(response_key) } diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 53523e0fd..117e7fc43 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -4,7 +4,10 @@ use bevy_ecs::{entity::Entity, prelude::Event}; use naia_client::{Events, NaiaClientError}; -use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_bevy_shared::{ + Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, + Request, ResponseSendKey, Tick, +}; use naia_client::shared::GlobalResponseId; // ConnectEvent diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index 69defe320..0436d3bc7 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -3,9 +3,9 @@ use std::{marker::PhantomData, ops::DerefMut, sync::Mutex}; use bevy_app::{App, Plugin as PluginType, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs}; +use crate::events::RequestEvents; use naia_bevy_shared::{BeforeReceiveEvents, Protocol, SharedPlugin, WorldData}; use naia_client::{Client, ClientConfig}; -use crate::events::RequestEvents; use super::{ client::ClientWrapper, diff --git a/adapters/bevy/client/src/systems.rs b/adapters/bevy/client/src/systems.rs index f0647016a..d5c1923b6 100644 --- a/adapters/bevy/client/src/systems.rs +++ b/adapters/bevy/client/src/systems.rs @@ -22,8 +22,8 @@ mod bevy_events { pub use crate::events::{ ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, EntityAuthDeniedEvent, EntityAuthGrantedEvent, EntityAuthResetEvent, ErrorEvent, InsertComponentEvents, - MessageEvents, PublishEntityEvent, RejectEvent, RemoveComponentEvents, ServerTickEvent, - SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, + MessageEvents, PublishEntityEvent, RejectEvent, RemoveComponentEvents, RequestEvents, + ServerTickEvent, SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvents, }; } @@ -33,13 +33,12 @@ pub fn before_receive_events(world: &mut World) { let host_id = TypeId::of::(); world.resource_scope(|world, mut client: Mut>| { - // Host Component Updates let mut other_host_component_events = Vec::new(); - let mut host_component_event_reader = world - .get_resource_mut::>() - .unwrap(); - let host_component_events: Vec = host_component_event_reader.drain().collect(); + let mut host_component_event_reader = + world.get_resource_mut::>().unwrap(); + let host_component_events: Vec = + host_component_event_reader.drain().collect(); for event in host_component_events { if event.host_id() != host_id { other_host_component_events.push(event); @@ -48,13 +47,20 @@ pub fn before_receive_events(world: &mut World) { match event { HostSyncEvent::Insert(_, entity, component_kind) => { let mut world_proxy = world.proxy_mut(); - let Some(mut component_mut) = world_proxy.component_mut_of_kind(&entity, &component_kind) else { + let Some(mut component_mut) = + world_proxy.component_mut_of_kind(&entity, &component_kind) + else { continue; }; - client.client.insert_component_worldless(&entity, DerefMut::deref_mut(&mut component_mut)); + client.client.insert_component_worldless( + &entity, + DerefMut::deref_mut(&mut component_mut), + ); } HostSyncEvent::Remove(_, entity, component_kind) => { - client.client.remove_component_worldless(&entity, &component_kind); + client + .client + .remove_component_worldless(&entity, &component_kind); } HostSyncEvent::Despawn(_, entity) => { client.client.despawn_entity_worldless(&entity); @@ -64,9 +70,7 @@ pub fn before_receive_events(world: &mut World) { // pass non-matching host component events to be handled elsewhere if !other_host_component_events.is_empty() { - let mut event_writer = world - .get_resource_mut::>() - .unwrap(); + let mut event_writer = world.get_resource_mut::>().unwrap(); for event in other_host_component_events { event_writer.send(event); } @@ -75,7 +79,6 @@ pub fn before_receive_events(world: &mut World) { // Receive Events let mut events = client.client.receive(world.proxy_mut()); if !events.is_empty() { - if events.has::() { // Connect Event let mut event_writer = world @@ -212,7 +215,10 @@ pub fn before_receive_events(world: &mut World) { if world.get_entity(entity).is_some() { world.entity_mut(entity).insert(HostOwned::new::()); } else { - warn!("Granted auth to an entity that no longer exists! {:?}", entity); + warn!( + "Granted auth to an entity that no longer exists! {:?}", + entity + ); } } } @@ -241,7 +247,10 @@ pub fn before_receive_events(world: &mut World) { if world.get_entity(entity).is_some() { world.entity_mut(entity).remove::(); } else { - warn!("Reset auth to an entity that no longer exists! {:?}", entity); + warn!( + "Reset auth to an entity that no longer exists! {:?}", + entity + ); } } } @@ -261,8 +270,7 @@ pub fn before_receive_events(world: &mut World) { let mut event_writer = world .get_resource_mut::>>() .unwrap(); - event_writer - .send(bevy_events::UpdateComponentEvents::::new(updates)); + event_writer.send(bevy_events::UpdateComponentEvents::::new(updates)); } // Remove Component Event diff --git a/adapters/bevy/server/src/commands.rs b/adapters/bevy/server/src/commands.rs index b4b8d790d..f636192de 100644 --- a/adapters/bevy/server/src/commands.rs +++ b/adapters/bevy/server/src/commands.rs @@ -13,12 +13,9 @@ use crate::{server::ServerWrapper, Server}; // Bevy Commands Extension pub trait CommandsExt<'a> { fn enable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a>; - fn disable_replication(&'a mut self, server: &mut Server) + fn disable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a>; + fn configure_replication(&'a mut self, config: ReplicationConfig) -> &'a mut EntityCommands<'a>; - fn configure_replication( - &'a mut self, - config: ReplicationConfig, - ) -> &'a mut EntityCommands<'a>; fn replication_config(&'a self, server: &Server) -> Option; fn give_authority( &'a mut self, @@ -38,10 +35,7 @@ impl<'a> CommandsExt<'a> for EntityCommands<'a> { return self; } - fn disable_replication( - &'a mut self, - server: &mut Server, - ) -> &'a mut EntityCommands<'a> { + fn disable_replication(&'a mut self, server: &mut Server) -> &'a mut EntityCommands<'a> { server.disable_replication(&self.id()); self.remove::(); return self; diff --git a/adapters/bevy/server/src/events.rs b/adapters/bevy/server/src/events.rs index f9e63598a..ac1eb6d53 100644 --- a/adapters/bevy/server/src/events.rs +++ b/adapters/bevy/server/src/events.rs @@ -2,7 +2,10 @@ use std::{any::Any, collections::HashMap}; use bevy_ecs::{entity::Entity, prelude::Event}; -use naia_bevy_shared::{Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_bevy_shared::{ + Channel, ChannelKind, ComponentKind, Message, MessageContainer, MessageKind, Replicate, + Request, ResponseSendKey, Tick, +}; use naia_server::{shared::GlobalResponseId, Events, NaiaServerError, User, UserKey}; // ConnectEvent @@ -94,7 +97,10 @@ fn convert_messages( // RequestEvents #[derive(Event)] pub struct RequestEvents { - inner: HashMap>>, + inner: HashMap< + ChannelKind, + HashMap>, + >, } impl From<&mut Events> for RequestEvents { @@ -116,20 +122,21 @@ impl RequestEvents { return Vec::new(); }; - let mut output_list: Vec<(UserKey, ResponseSendKey, Q)> = Vec::new(); + let mut output_list: Vec<(UserKey, ResponseSendKey, Q)> = Vec::new(); - for (user_key, global_response_id, request) in requests { - let message: Q = Box::::downcast::(request.clone().to_boxed_any()) + for (user_key, global_response_id, request) in requests { + let message: Q = + Box::::downcast::(request.clone().to_boxed_any()) .ok() .map(|boxed_m| *boxed_m) .unwrap(); - let response_send_key = ResponseSendKey::new(*global_response_id); + let response_send_key = ResponseSendKey::new(*global_response_id); - output_list.push((*user_key, response_send_key, message)); - } + output_list.push((*user_key, response_send_key, message)); + } - return output_list; + return output_list; } } diff --git a/adapters/bevy/server/src/lib.rs b/adapters/bevy/server/src/lib.rs index f63aebf4d..82f268c0a 100644 --- a/adapters/bevy/server/src/lib.rs +++ b/adapters/bevy/server/src/lib.rs @@ -2,8 +2,8 @@ pub use naia_bevy_shared::{EntityAuthStatus, Random, ReceiveEvents, Replicate, T pub use naia_server::{ shared::{ default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, - FileBitWriter, SerdeErr, SignedInteger, SignedVariableInteger, UnsignedInteger, - UnsignedVariableInteger, ResponseReceiveKey, + FileBitWriter, ResponseReceiveKey, SerdeErr, SignedInteger, SignedVariableInteger, + UnsignedInteger, UnsignedVariableInteger, }, transport, ReplicationConfig, RoomKey, SerdeBevy as Serde, ServerConfig, UserKey, }; diff --git a/adapters/bevy/server/src/plugin.rs b/adapters/bevy/server/src/plugin.rs index 7c1428451..25b42473d 100644 --- a/adapters/bevy/server/src/plugin.rs +++ b/adapters/bevy/server/src/plugin.rs @@ -10,7 +10,7 @@ use super::{ events::{ AuthEvents, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, InsertComponentEvents, MessageEvents, PublishEntityEvent, RemoveComponentEvents, - SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, + RequestEvents, SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, }, server::ServerWrapper, systems::before_receive_events, diff --git a/adapters/bevy/server/src/server.rs b/adapters/bevy/server/src/server.rs index adb612fa2..08d1d58c4 100644 --- a/adapters/bevy/server/src/server.rs +++ b/adapters/bevy/server/src/server.rs @@ -2,12 +2,19 @@ use std::time::Duration; use bevy_ecs::{ entity::Entity, - system::{ResMut, SystemParam, Resource}, + system::{ResMut, Resource, SystemParam}, }; -use naia_server::{shared::SocketConfig, transport::Socket, ReplicationConfig, RoomKey, RoomMut, RoomRef, Server as NaiaServer, TickBufferMessages, UserKey, UserMut, UserRef, UserScopeMut, NaiaServerError, UserScopeRef}; +use naia_server::{ + shared::SocketConfig, transport::Socket, NaiaServerError, ReplicationConfig, RoomKey, RoomMut, + RoomRef, Server as NaiaServer, TickBufferMessages, UserKey, UserMut, UserRef, UserScopeMut, + UserScopeRef, +}; -use naia_bevy_shared::{Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick}; +use naia_bevy_shared::{ + Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError, + GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick, +}; #[derive(Resource)] pub struct ServerWrapper(pub NaiaServer); @@ -59,17 +66,27 @@ impl<'w> Server<'w> { self.server.0.receive_tick_buffer_messages(tick) } - /// Requests /// - pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Result, NaiaServerError> { + pub fn send_request( + &mut self, + user_key: &UserKey, + request: &Q, + ) -> Result, NaiaServerError> { self.server.0.send_request::(user_key, request) } - pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { + pub fn send_response( + &mut self, + response_key: &ResponseSendKey, + response: &S, + ) -> bool { self.server.0.send_response(response_key, response) } - pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option<(UserKey, S)> { + pub fn receive_response( + &mut self, + response_key: &ResponseReceiveKey, + ) -> Option<(UserKey, S)> { self.server.0.receive_response(response_key) } diff --git a/adapters/bevy/server/src/systems.rs b/adapters/bevy/server/src/systems.rs index 0df10f957..68ab47818 100644 --- a/adapters/bevy/server/src/systems.rs +++ b/adapters/bevy/server/src/systems.rs @@ -14,9 +14,8 @@ use crate::{plugin::Singleton, server::ServerWrapper, ClientOwned, EntityAuthSta mod naia_events { pub use naia_server::{ ConnectEvent, DelegateEntityEvent, DespawnEntityEvent, DisconnectEvent, - EntityAuthGrantEvent, EntityAuthResetEvent, ErrorEvent, - PublishEntityEvent, SpawnEntityEvent, TickEvent, - UnpublishEntityEvent, + EntityAuthGrantEvent, EntityAuthResetEvent, ErrorEvent, PublishEntityEvent, + SpawnEntityEvent, TickEvent, UnpublishEntityEvent, }; } @@ -24,7 +23,7 @@ mod bevy_events { pub use crate::events::{ AuthEvents, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, InsertComponentEvents, MessageEvents, PublishEntityEvent, RemoveComponentEvents, - SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, + RequestEvents, SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, }; } diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 544e9d3a6..c085b64e0 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -7,9 +7,10 @@ pub use naia_shared::{ LocalEntityAndGlobalEntityConverterMut, MessageBevy as Message, MessageBuilder, MessageContainer, MessageKind, MessageKinds, Named, OwnedBitReader, Property, PropertyMutate, PropertyMutator, Random, ReliableSettings, RemoteEntity, ReplicaDynMut, ReplicaDynRef, - ReplicateBevy as Replicate, ReplicateBuilder, SerdeBevyShared as Serde, SerdeErr, - SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, Timer, - UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, Request, Response, ResponseSendKey, ResponseReceiveKey + ReplicateBevy as Replicate, ReplicateBuilder, Request, Response, ResponseReceiveKey, + ResponseSendKey, SerdeBevyShared as Serde, SerdeErr, SerdeIntegerConversion, SignedInteger, + SignedVariableInteger, Tick, TickBufferSettings, Timer, UnsignedInteger, + UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, }; mod change_detection; diff --git a/adapters/bevy/shared/src/protocol.rs b/adapters/bevy/shared/src/protocol.rs index 6dc3b1bb1..71ace73dc 100644 --- a/adapters/bevy/shared/src/protocol.rs +++ b/adapters/bevy/shared/src/protocol.rs @@ -1,6 +1,9 @@ use std::time::Duration; -use naia_shared::{Channel, ChannelDirection, ChannelMode, ComponentKind, CompressionConfig, LinkConditionerConfig, Message, Protocol as InnerProtocol, Replicate, Request}; +use naia_shared::{ + Channel, ChannelDirection, ChannelMode, ComponentKind, CompressionConfig, + LinkConditionerConfig, Message, Protocol as InnerProtocol, Replicate, Request, +}; use crate::{ProtocolPlugin, WorldData}; diff --git a/client/src/client.rs b/client/src/client.rs index 23154a10e..2d7078fc2 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -2,7 +2,15 @@ use std::{any::Any, collections::VecDeque, hash::Hash, net::SocketAddr}; use log::{info, warn}; -use naia_shared::{BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; +use naia_shared::{ + BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, + EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, + EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, + GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, + PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, + ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, + Tick, WorldMutType, WorldRefType, +}; use super::{client_config::ClientConfig, error::NaiaClientError, events::Events}; use crate::{ @@ -297,8 +305,10 @@ impl Client { } // - pub fn send_request(&mut self, request: &Q) -> Result, NaiaClientError> { - + pub fn send_request( + &mut self, + request: &Q, + ) -> Result, NaiaClientError> { let cloned_request = Q::clone_box(request); // let response_type_id = TypeId::of::(); let id = self.send_request_inner(&ChannelKind::of::(), cloned_request)?; @@ -311,7 +321,6 @@ impl Client { // response_type_id: TypeId, request_box: Box, ) -> Result { - let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); if !channel_settings.can_request_and_respond() { @@ -320,7 +329,9 @@ impl Client { let Some(connection) = &mut self.server_connection else { warn!("currently not connected to server"); - return Err(NaiaClientError::Message("currently not connected to server".to_string())); + return Err(NaiaClientError::Message( + "currently not connected to server".to_string(), + )); }; let mut converter = EntityConverterMut::new( &self.global_world_manager, @@ -341,8 +352,11 @@ impl Client { } /// Sends a Response for a given Request. Returns whether or not was successful. - pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { - + pub fn send_response( + &mut self, + response_key: &ResponseSendKey, + response: &S, + ) -> bool { let response_id = response_key.response_id(); let cloned_response = S::clone_box(response); @@ -359,7 +373,10 @@ impl Client { let Some(connection) = &mut self.server_connection else { return false; }; - let Some((channel_kind, local_response_id)) = connection.global_response_manager.destroy_response_id(response_id) else { + let Some((channel_kind, local_response_id)) = connection + .global_response_manager + .destroy_response_id(response_id) + else { return false; }; let mut converter = EntityConverterMut::new( @@ -378,12 +395,18 @@ impl Client { return true; } - pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option { + pub fn receive_response( + &mut self, + response_key: &ResponseReceiveKey, + ) -> Option { let Some(connection) = &mut self.server_connection else { return None; }; let request_id = response_key.request_id(); - let Some(container) = connection.global_request_manager.destroy_request_id(&request_id) else { + let Some(container) = connection + .global_request_manager + .destroy_request_id(&request_id) + else { return None; }; let response: S = Box::::downcast::(container.to_boxed_any()) diff --git a/client/src/connection/connection.rs b/client/src/connection/connection.rs index f00d64dc8..f94d8f584 100644 --- a/client/src/connection/connection.rs +++ b/client/src/connection/connection.rs @@ -2,18 +2,23 @@ use std::{any::Any, hash::Hash}; use log::warn; -use naia_shared::{BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, EntityEventMessage, EntityEventMessageAction, EntityResponseEvent, HostType, HostWorldEvents, Instant, OwnedBitReader, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; +use naia_shared::{ + BaseConnection, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, + EntityEventMessage, EntityEventMessageAction, EntityResponseEvent, HostType, HostWorldEvents, + Instant, OwnedBitReader, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, + Tick, WorldMutType, WorldRefType, +}; +use crate::request::GlobalRequestManager; use crate::{ - request::GlobalResponseManager, connection::{ io::Io, tick_buffer_sender::TickBufferSender, tick_queue::TickQueue, time_manager::TimeManager, }, events::Events, + request::GlobalResponseManager, world::global_world_manager::GlobalWorldManager, }; -use crate::request::GlobalRequestManager; pub struct Connection { pub base: BaseConnection, @@ -125,9 +130,11 @@ impl Connection { for (channel_kind, messages) in messages { if channel_kind == ChannelKind::of::() { for message in messages { - let Some(event_message) = Box::::downcast::(message.to_boxed_any()) - .ok() - .map(|boxed_m| *boxed_m) else { + let Some(event_message) = Box::::downcast::< + EntityEventMessage, + >(message.to_boxed_any()) + .ok() + .map(|boxed_m| *boxed_m) else { panic!("Received unknown message over SystemChannel!"); }; match event_message.entity.get(global_world_manager) { @@ -161,13 +168,16 @@ impl Connection { // Requests for (channel_kind, requests) in requests { for (local_response_id, request) in requests { - let global_response_id = self.global_response_manager.create_response_id(&channel_kind, &local_response_id); + let global_response_id = self + .global_response_manager + .create_response_id(&channel_kind, &local_response_id); incoming_events.push_request(&channel_kind, global_response_id, request); } } // Responses for (global_request_id, response) in responses { - self.global_request_manager.receive_response(&global_request_id, response); + self.global_request_manager + .receive_response(&global_request_id, response); } // Receive World Events diff --git a/client/src/connection/handshake_manager.rs b/client/src/connection/handshake_manager.rs index b48f64848..ae81c4fc0 100644 --- a/client/src/connection/handshake_manager.rs +++ b/client/src/connection/handshake_manager.rs @@ -160,7 +160,9 @@ impl HandshakeManager { success = success_inner; } if success { - let HandshakeState::TimeSync(time_manager) = std::mem::replace(&mut self.connection_state, HandshakeState::Connected) else { + let HandshakeState::TimeSync(time_manager) = + std::mem::replace(&mut self.connection_state, HandshakeState::Connected) + else { panic!("should be impossible due to check above"); }; self.connection_state = @@ -253,7 +255,9 @@ impl HandshakeManager { // Step 6 of Handshake fn recv_connect_response(&mut self) -> Option { - let HandshakeState::AwaitingConnectResponse(time_manager) = std::mem::replace(&mut self.connection_state, HandshakeState::Connected) else { + let HandshakeState::AwaitingConnectResponse(time_manager) = + std::mem::replace(&mut self.connection_state, HandshakeState::Connected) + else { return None; }; diff --git a/client/src/events.rs b/client/src/events.rs index ae0e76a01..65b2b2091 100644 --- a/client/src/events.rs +++ b/client/src/events.rs @@ -1,6 +1,9 @@ use std::{collections::HashMap, marker::PhantomData, mem, net::SocketAddr, vec::IntoIter}; -use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, GlobalResponseId, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_shared::{ + Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, GlobalResponseId, + Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick, +}; use crate::NaiaClientError; diff --git a/client/src/lib.rs b/client/src/lib.rs index 145a86fd5..9d8f43167 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -16,8 +16,8 @@ extern crate cfg_if; pub mod transport; pub mod shared { pub use naia_shared::{ - default_channels, sequence_greater_than, Instant, Message, Protocol, Random, SocketConfig, - Tick, GlobalRequestId, GlobalResponseId, ResponseReceiveKey + default_channels, sequence_greater_than, GlobalRequestId, GlobalResponseId, Instant, + Message, Protocol, Random, ResponseReceiveKey, SocketConfig, Tick, }; } pub mod internal { @@ -30,8 +30,8 @@ mod command_history; mod connection; mod error; mod events; -mod world; mod request; +mod world; pub use client::{Client, ConnectionStatus}; pub use client_config::ClientConfig; @@ -40,8 +40,8 @@ pub use error::NaiaClientError; pub use events::{ ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, EntityAuthDeniedEvent, EntityAuthGrantedEvent, EntityAuthResetEvent, ErrorEvent, Events, InsertComponentEvent, - MessageEvent, PublishEntityEvent, RejectEvent, RemoveComponentEvent, ServerTickEvent, - SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvent, RequestEvent, + MessageEvent, PublishEntityEvent, RejectEvent, RemoveComponentEvent, RequestEvent, + ServerTickEvent, SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvent, }; pub use world::{ entity_mut::EntityMut, entity_ref::EntityRef, replication_config::ReplicationConfig, diff --git a/client/src/request.rs b/client/src/request.rs index e6566d7da..408985e11 100644 --- a/client/src/request.rs +++ b/client/src/request.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer}; +use naia_shared::{ + ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer, +}; // GlobalRequestManager pub struct GlobalRequestManager { @@ -25,7 +27,10 @@ impl GlobalRequestManager { id } - pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option { + pub(crate) fn destroy_request_id( + &mut self, + request_id: &GlobalRequestId, + ) -> Option { let Some(response_opt) = self.map.get(request_id) else { return None; }; @@ -36,13 +41,16 @@ impl GlobalRequestManager { return None; } - pub(crate) fn receive_response(&mut self, request_id: &GlobalRequestId, response: MessageContainer) { + pub(crate) fn receive_response( + &mut self, + request_id: &GlobalRequestId, + response: MessageContainer, + ) { let response_opt = self.map.get_mut(request_id).unwrap(); *response_opt = Some(response); } } - // GlobalResponseManager pub struct GlobalResponseManager { map: HashMap, @@ -57,16 +65,24 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, channel_kind: &ChannelKind, local_response_id: &LocalResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id( + &mut self, + channel_kind: &ChannelKind, + local_response_id: &LocalResponseId, + ) -> GlobalResponseId { let id = GlobalResponseId::new(self.next_id); self.next_id = self.next_id.wrapping_add(1); - self.map.insert(id, (channel_kind.clone(), local_response_id.clone())); + self.map + .insert(id, (channel_kind.clone(), local_response_id.clone())); id } - pub(crate) fn destroy_response_id(&mut self, global_response_id: &GlobalResponseId) -> Option<(ChannelKind, LocalResponseId)> { + pub(crate) fn destroy_response_id( + &mut self, + global_response_id: &GlobalResponseId, + ) -> Option<(ChannelKind, LocalResponseId)> { self.map.remove(global_response_id) } -} \ No newline at end of file +} diff --git a/client/src/world/global_world_manager.rs b/client/src/world/global_world_manager.rs index fe4cf7224..251373eaa 100644 --- a/client/src/world/global_world_manager.rs +++ b/client/src/world/global_world_manager.rs @@ -244,7 +244,7 @@ impl GlobalWorldManager { } pub(crate) fn entity_request_authority(&mut self, entity: &E) -> bool { - let Some(auth_status) = self.auth_handler.auth_status(entity) else { + let Some(auth_status) = self.auth_handler.auth_status(entity) else { panic!("Can only request authority for an Entity that is Delegated!"); }; if !auth_status.can_request() { diff --git a/demos/basic/client/app/src/app.rs b/demos/basic/client/app/src/app.rs index fbaafb99f..89bb16100 100644 --- a/demos/basic/client/app/src/app.rs +++ b/demos/basic/client/app/src/app.rs @@ -9,14 +9,14 @@ cfg_if! { use naia_client::{ shared::{default_channels::UnorderedReliableChannel, SocketConfig}, transport::webrtc, - Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, - DespawnEntityEvent, DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, - RemoveComponentEvent, SpawnEntityEvent, UpdateComponentEvent, + Client as NaiaClient, ClientConfig, ClientTickEvent, ConnectEvent, DespawnEntityEvent, + DisconnectEvent, ErrorEvent, MessageEvent, RejectEvent, RemoveComponentEvent, SpawnEntityEvent, + UpdateComponentEvent, }; use naia_demo_world::{Entity, World}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, MyMarker}; +use naia_basic_demo_shared::{protocol, Auth, Character, MyMarker, StringMessage}; type Client = NaiaClient; @@ -76,7 +76,9 @@ impl App { for server_address in events.read::() { info!("Client disconnected from: {}", server_address); } - for message in events.read::>>() { + for message in + events.read::>>() + { let message_contents = &(*message.contents); info!("Client recv <- {}", message_contents); diff --git a/demos/basic/server/src/app.rs b/demos/basic/server/src/app.rs index eda1007ac..2158ab35d 100644 --- a/demos/basic/server/src/app.rs +++ b/demos/basic/server/src/app.rs @@ -8,7 +8,7 @@ use naia_server::{ use naia_demo_world::{Entity, World, WorldRefType}; -use naia_basic_demo_shared::{protocol, Auth, Character, StringMessage, MyMarker}; +use naia_basic_demo_shared::{protocol, Auth, Character, MyMarker, StringMessage}; type Server = NaiaServer; @@ -59,7 +59,8 @@ impl App { count += 1; // Create a Character - let character = Character::::new(MyMarker, (count * 4) as u8, 0, first, last); + let character = + Character::::new(MyMarker, (count * 4) as u8, 0, first, last); let character_key = server .spawn_entity(world.proxy_mut()) .insert_component(character) @@ -129,7 +130,8 @@ impl App { new_message_contents ); - let new_message = StringMessage::::new(new_message_contents, MyMarker); + let new_message = + StringMessage::::new(new_message_contents, MyMarker); self.server .send_message::(&user_key, &new_message); } @@ -151,7 +153,9 @@ impl App { let server = &mut self.server; let world = &self.world; for (_, user_key, entity) in server.scope_checks() { - if let Some(character) = world.proxy().component::>(&entity) { + if let Some(character) = + world.proxy().component::>(&entity) + { let x = *character.x; let should_be_in_scope = (5..=15).contains(&x); let is_in_scope = server.user_scope(&user_key).has(&entity); diff --git a/demos/basic/shared/src/lib.rs b/demos/basic/shared/src/lib.rs index 9b603e23d..42bb6f034 100644 --- a/demos/basic/shared/src/lib.rs +++ b/demos/basic/shared/src/lib.rs @@ -1,3 +1,5 @@ mod protocol; -pub use protocol::{protocol, Auth, Character, StringMessage, BasicRequest, BasicResponse, MyMarker}; +pub use protocol::{ + protocol, Auth, BasicRequest, BasicResponse, Character, MyMarker, StringMessage, +}; diff --git a/demos/basic/shared/src/protocol/basic_request.rs b/demos/basic/shared/src/protocol/basic_request.rs index a824e8b7a..fefd243e9 100644 --- a/demos/basic/shared/src/protocol/basic_request.rs +++ b/demos/basic/shared/src/protocol/basic_request.rs @@ -26,4 +26,4 @@ impl BasicResponse { pub fn new(contents: String) -> Self { Self { contents } } -} \ No newline at end of file +} diff --git a/demos/basic/shared/src/protocol/character.rs b/demos/basic/shared/src/protocol/character.rs index 8a123ef6d..3b4677f13 100644 --- a/demos/basic/shared/src/protocol/character.rs +++ b/demos/basic/shared/src/protocol/character.rs @@ -1,4 +1,3 @@ - use naia_shared::{Property, Replicate, Serde}; /// Here's an example of a Custom Property diff --git a/demos/basic/shared/src/protocol/mod.rs b/demos/basic/shared/src/protocol/mod.rs index 803b99527..220a3a064 100644 --- a/demos/basic/shared/src/protocol/mod.rs +++ b/demos/basic/shared/src/protocol/mod.rs @@ -3,14 +3,14 @@ use std::time::Duration; use naia_shared::{LinkConditionerConfig, Protocol, Serde}; mod auth; +mod basic_request; mod character; mod string_message; -mod basic_request; pub use auth::Auth; +pub use basic_request::{BasicRequest, BasicResponse}; pub use character::Character; pub use string_message::StringMessage; -pub use basic_request::{BasicRequest, BasicResponse}; #[derive(Serde, PartialEq, Clone, Default)] pub struct MyMarker; diff --git a/demos/basic/shared/src/protocol/string_message.rs b/demos/basic/shared/src/protocol/string_message.rs index e2436a709..cd15b915d 100644 --- a/demos/basic/shared/src/protocol/string_message.rs +++ b/demos/basic/shared/src/protocol/string_message.rs @@ -1,4 +1,3 @@ - use naia_shared::{Message, Serde}; #[derive(Message)] @@ -9,6 +8,9 @@ pub struct StringMessage { impl StringMessage { pub fn new(contents: String, something: T) -> Self { - Self { contents, something } + Self { + contents, + something, + } } } diff --git a/demos/bevy/client/src/app.rs b/demos/bevy/client/src/app.rs index 4d57e8c63..f230aedb4 100644 --- a/demos/bevy/client/src/app.rs +++ b/demos/bevy/client/src/app.rs @@ -24,7 +24,10 @@ pub fn run() { // Bevy Plugins .add_plugins(DefaultPlugins) // Add Naia Client Plugin - .add_plugins(ClientPlugin::
::new(ClientConfig::default(), protocol())) + .add_plugins(ClientPlugin::
::new( + ClientConfig::default(), + protocol(), + )) // Background Color .insert_resource(ClearColor(Color::BLACK)) // Startup System diff --git a/demos/bevy/client/src/systems/events.rs b/demos/bevy/client/src/systems/events.rs index 14ded53d0..85a34c7d8 100644 --- a/demos/bevy/client/src/systems/events.rs +++ b/demos/bevy/client/src/systems/events.rs @@ -12,21 +12,22 @@ use bevy::{ use naia_bevy_client::{ events::{ ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, InsertComponentEvents, - MessageEvents, PublishEntityEvent, RejectEvent, RemoveComponentEvents, SpawnEntityEvent, - UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, + MessageEvents, PublishEntityEvent, RejectEvent, RemoveComponentEvents, RequestEvents, + SpawnEntityEvent, UnpublishEntityEvent, UpdateComponentEvents, }, sequence_greater_than, Client, CommandsExt, Random, Replicate, Tick, }; use naia_bevy_demo_shared::{ behavior as shared_behavior, - channels::{RequestChannel, EntityAssignmentChannel, PlayerCommandChannel}, + channels::{EntityAssignmentChannel, PlayerCommandChannel, RequestChannel}, components::{Color, ColorValue, Position, Shape, ShapeValue}, messages::{BasicRequest, BasicResponse, EntityAssignment, KeyCommand}, }; use crate::{ + app::Main, components::{Confirmed, Interp, LocalCursor, Predicted}, - resources::{Global, OwnedEntity}, app::Main, + resources::{Global, OwnedEntity}, }; const SQUARE_SIZE: f32 = 32.0; @@ -99,10 +100,9 @@ pub fn message_events( // Here we create a local copy of the Player entity, to use for client-side prediction if let Ok(position) = position_query.get(entity) { - let prediction_entity = commands - .entity(entity) - .local_duplicate(); // copies all Replicate components as well - commands.entity(prediction_entity) + let prediction_entity = commands.entity(entity).local_duplicate(); // copies all Replicate components as well + commands + .entity(prediction_entity) .insert(SpriteBundle { sprite: Sprite { custom_size: Some(Vec2::new(SQUARE_SIZE, SQUARE_SIZE)), @@ -178,10 +178,7 @@ pub fn request_events( } } -pub fn response_events( - mut client: Client
, - mut global: ResMut, -) { +pub fn response_events(mut client: Client
, mut global: ResMut) { let mut finished_response_keys = Vec::new(); for response_key in &global.response_keys { if let Some(response) = client.receive_response(response_key) { @@ -379,7 +376,8 @@ pub fn tick_events( let Some(predicted_entity) = global .owned_entity .as_ref() - .map(|owned_entity| owned_entity.predicted) else { + .map(|owned_entity| owned_entity.predicted) + else { // No owned Entity return; }; diff --git a/demos/bevy/client/src/systems/init.rs b/demos/bevy/client/src/systems/init.rs index a9b1b63b3..a570b14bb 100644 --- a/demos/bevy/client/src/systems/init.rs +++ b/demos/bevy/client/src/systems/init.rs @@ -1,7 +1,7 @@ - -use bevy::{prelude::{ - Assets, Camera2dBundle, Color, ColorMaterial, Commands, Mesh, ResMut, Circle, -}, log::info}; +use bevy::{ + log::info, + prelude::{Assets, Camera2dBundle, Circle, Color, ColorMaterial, Commands, Mesh, ResMut}, +}; use naia_bevy_client::{transport::webrtc, Client}; use naia_bevy_demo_shared::messages::Auth; diff --git a/demos/bevy/client/src/systems/input.rs b/demos/bevy/client/src/systems/input.rs index f9647db51..5d3240dc3 100644 --- a/demos/bevy/client/src/systems/input.rs +++ b/demos/bevy/client/src/systems/input.rs @@ -3,7 +3,7 @@ use bevy::prelude::{ButtonInput, Commands, KeyCode, Query, Res, ResMut, Vec2, Wi use naia_bevy_client::{Client, CommandsExt, ReplicationConfig}; use naia_bevy_demo_shared::{components::Position, messages::KeyCommand}; -use crate::{resources::Global, app::Main}; +use crate::{app::Main, resources::Global}; pub fn key_input( client: Client
, @@ -68,7 +68,7 @@ pub fn cursor_input( fn window_relative_mouse_position(window: &Window) -> Option { let Some(cursor_pos) = window.cursor_position() else { - return None + return None; }; Some(Vec2::new( diff --git a/demos/bevy/client/src/systems/sync.rs b/demos/bevy/client/src/systems/sync.rs index f2d27729d..5ed83ab8f 100644 --- a/demos/bevy/client/src/systems/sync.rs +++ b/demos/bevy/client/src/systems/sync.rs @@ -3,7 +3,10 @@ use bevy::prelude::{Query, Transform, With}; use naia_bevy_client::Client; use naia_bevy_demo_shared::components::Position; -use crate::{app::Main, components::{Confirmed, Interp, LocalCursor, Predicted}}; +use crate::{ + app::Main, + components::{Confirmed, Interp, LocalCursor, Predicted}, +}; pub fn sync_clientside_sprites( client: Client
, diff --git a/demos/bevy/server/src/resources.rs b/demos/bevy/server/src/resources.rs index a5b6a3980..df50a1a07 100644 --- a/demos/bevy/server/src/resources.rs +++ b/demos/bevy/server/src/resources.rs @@ -3,7 +3,7 @@ use std::collections::{HashMap, HashSet}; use bevy_ecs::{entity::Entity, prelude::Resource}; use naia_bevy_demo_shared::messages::BasicResponse; -use naia_bevy_server::{RoomKey, UserKey, ResponseReceiveKey}; +use naia_bevy_server::{ResponseReceiveKey, RoomKey, UserKey}; #[derive(Resource)] pub struct Global { diff --git a/demos/bevy/server/src/systems/events.rs b/demos/bevy/server/src/systems/events.rs index 1938d0310..caafc16de 100644 --- a/demos/bevy/server/src/systems/events.rs +++ b/demos/bevy/server/src/systems/events.rs @@ -7,17 +7,17 @@ use bevy_log::info; use naia_bevy_server::{ events::{ AuthEvents, ConnectEvent, DespawnEntityEvent, DisconnectEvent, ErrorEvent, - InsertComponentEvents, PublishEntityEvent, RemoveComponentEvents, SpawnEntityEvent, - TickEvent, UnpublishEntityEvent, UpdateComponentEvents, RequestEvents, + InsertComponentEvents, PublishEntityEvent, RemoveComponentEvents, RequestEvents, + SpawnEntityEvent, TickEvent, UnpublishEntityEvent, UpdateComponentEvents, }, CommandsExt, Random, ReplicationConfig, Server, }; use naia_bevy_demo_shared::{ behavior as shared_behavior, - channels::{RequestChannel, EntityAssignmentChannel, PlayerCommandChannel}, + channels::{EntityAssignmentChannel, PlayerCommandChannel, RequestChannel}, components::{Color, ColorValue, Position, Shape, ShapeValue}, - messages::{Auth, EntityAssignment, KeyCommand, BasicRequest, BasicResponse}, + messages::{Auth, BasicRequest, BasicResponse, EntityAssignment, KeyCommand}, }; use crate::resources::Global; @@ -138,13 +138,18 @@ pub fn tick_events( // Send a request to all clients if server_tick % 100 == 0 { - for user_key in server.user_keys() { let request = BasicRequest::new("ServerRequest".to_string(), global.request_index); global.request_index = global.request_index.wrapping_add(1); let user = server.user(&user_key); - info!("Server sending Request -> Client ({}): {:?}", user.address(), request); - let Ok(response_key) = server.send_request::(&user_key, &request) else { + info!( + "Server sending Request -> Client ({}): {:?}", + user.address(), + request + ); + let Ok(response_key) = + server.send_request::(&user_key, &request) + else { info!("Failed to send request to user: {:?}", user_key); continue; }; @@ -170,30 +175,37 @@ pub fn tick_events( } } -pub fn request_events( - mut server: Server, - mut event_reader: EventReader, -) { +pub fn request_events(mut server: Server, mut event_reader: EventReader) { for events in event_reader.read() { - for (user_key, response_send_key, request) in events.read::() { + for (user_key, response_send_key, request) in events.read::() + { let user = server.user(&user_key); - info!("Server received Request <- Client({}): {:?}", user.address(), request); + info!( + "Server received Request <- Client({}): {:?}", + user.address(), + request + ); let response = BasicResponse::new("ServerResponse".to_string(), request.index); - info!("Server sending Response -> Client({}): {:?}", user.address(), response); + info!( + "Server sending Response -> Client({}): {:?}", + user.address(), + response + ); server.send_response(&response_send_key, &response); } } } -pub fn response_events( - mut server: Server, - mut global: ResMut, -) { +pub fn response_events(mut server: Server, mut global: ResMut) { let mut finished_response_keys = Vec::new(); for response_key in &global.response_keys { if let Some((user_key, response)) = server.receive_response(response_key) { let user = server.user(&user_key); - info!("Server received Response <- Client({:?}): {:?}", user.address(), response); + info!( + "Server received Response <- Client({:?}): {:?}", + user.address(), + response + ); finished_response_keys.push(response_key.clone()); } } diff --git a/demos/bevy/shared/src/messages/basic_request.rs b/demos/bevy/shared/src/messages/basic_request.rs index 34eb3db2c..3dd860136 100644 --- a/demos/bevy/shared/src/messages/basic_request.rs +++ b/demos/bevy/shared/src/messages/basic_request.rs @@ -22,12 +22,10 @@ pub struct BasicResponse { pub index: u8, } -impl Response for BasicResponse { - -} +impl Response for BasicResponse {} impl BasicResponse { pub fn new(contents: String, index: u8) -> Self { Self { contents, index } } -} \ No newline at end of file +} diff --git a/demos/bevy/shared/src/messages/mod.rs b/demos/bevy/shared/src/messages/mod.rs index 09d57afac..b261dafa0 100644 --- a/demos/bevy/shared/src/messages/mod.rs +++ b/demos/bevy/shared/src/messages/mod.rs @@ -1,14 +1,14 @@ use naia_bevy_shared::{Protocol, ProtocolPlugin}; mod auth; +mod basic_request; mod entity_assignment; mod key_command; -mod basic_request; pub use auth::Auth; +pub use basic_request::{BasicRequest, BasicResponse}; pub use entity_assignment::EntityAssignment; pub use key_command::KeyCommand; -pub use basic_request::{BasicRequest, BasicResponse}; // Plugin pub struct MessagesPlugin; diff --git a/demos/demo_utils/demo_world/src/world.rs b/demos/demo_utils/demo_world/src/world.rs index d52d63288..4dfea9db7 100644 --- a/demos/demo_utils/demo_world/src/world.rs +++ b/demos/demo_utils/demo_world/src/world.rs @@ -324,8 +324,11 @@ impl<'w> WorldMutType for WorldMut<'w> { if let Some(component_map) = self.world.entities.get_mut(entity) { if let Some(component) = component_map.get_mut(component_kind) { let diff_mask_size = component.diff_mask_size(); - let mutator = - global_world_manager.register_component(entity, &component_kind, diff_mask_size); + let mutator = global_world_manager.register_component( + entity, + &component_kind, + diff_mask_size, + ); component.publish(&mutator); } } diff --git a/server/src/connection/connection.rs b/server/src/connection/connection.rs index 7df484adf..f5596cb40 100644 --- a/server/src/connection/connection.rs +++ b/server/src/connection/connection.rs @@ -2,8 +2,13 @@ use std::{any::Any, hash::Hash, net::SocketAddr}; use log::warn; -use naia_shared::{BaseConnection, BigMapKey, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, EntityEventMessage, EntityResponseEvent, HostType, HostWorldEvents, Instant, PacketType, Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; +use naia_shared::{ + BaseConnection, BigMapKey, BitReader, BitWriter, ChannelKind, ChannelKinds, ConnectionConfig, + EntityEventMessage, EntityResponseEvent, HostType, HostWorldEvents, Instant, PacketType, + Protocol, Serde, SerdeErr, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType, +}; +use crate::request::{GlobalRequestManager, GlobalResponseManager}; use crate::{ connection::{ io::Io, ping_config::PingConfig, tick_buffer_messages::TickBufferMessages, @@ -14,7 +19,6 @@ use crate::{ user::UserKey, world::global_world_manager::GlobalWorldManager, }; -use crate::request::{GlobalRequestManager, GlobalResponseManager}; use super::ping_manager::PingManager; @@ -113,9 +117,11 @@ impl Connection { for (channel_kind, messages) in messages { if channel_kind == ChannelKind::of::() { for message in messages { - let Some(event_message) = Box::::downcast::(message.to_boxed_any()) - .ok() - .map(|boxed_m| *boxed_m) else { + let Some(event_message) = Box::::downcast::< + EntityEventMessage, + >(message.to_boxed_any()) + .ok() + .map(|boxed_m| *boxed_m) else { panic!("Received unknown message over SystemChannel!"); }; match event_message.entity.get(global_world_manager) { @@ -142,8 +148,17 @@ impl Connection { // Requests for (channel_kind, requests) in requests { for (local_response_id, request) in requests { - let global_response_id = global_response_manager.create_response_id(&self.user_key, &channel_kind, &local_response_id); - incoming_events.push_request(&self.user_key, &channel_kind, global_response_id, request); + let global_response_id = global_response_manager.create_response_id( + &self.user_key, + &channel_kind, + &local_response_id, + ); + incoming_events.push_request( + &self.user_key, + &channel_kind, + global_response_id, + request, + ); } } // Responses diff --git a/server/src/connection/handshake_manager.rs b/server/src/connection/handshake_manager.rs index 95df6472b..fe8dc93e8 100644 --- a/server/src/connection/handshake_manager.rs +++ b/server/src/connection/handshake_manager.rs @@ -3,9 +3,8 @@ use std::{collections::HashMap, hash::Hash, net::SocketAddr}; use ring::{hmac, rand}; pub use naia_shared::{ - BitReader, BitWriter, FakeEntityConverter, - MessageContainer, MessageKinds, PacketType, - Serde, SerdeErr, StandardHeader, + BitReader, BitWriter, FakeEntityConverter, MessageContainer, MessageKinds, PacketType, Serde, + SerdeErr, StandardHeader, }; use crate::{cache_map::CacheMap, connection::connection::Connection}; diff --git a/server/src/events.rs b/server/src/events.rs index 227627aac..04d9f9af9 100644 --- a/server/src/events.rs +++ b/server/src/events.rs @@ -2,7 +2,10 @@ use std::{any::Any, collections::HashMap, marker::PhantomData, mem, vec::IntoIte use log::warn; -use naia_shared::{Channel, ChannelKind, ComponentKind, EntityEvent, GlobalResponseId, EntityResponseEvent, Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick}; +use naia_shared::{ + Channel, ChannelKind, ComponentKind, EntityEvent, EntityResponseEvent, GlobalResponseId, + Message, MessageContainer, MessageKind, Replicate, Request, ResponseSendKey, Tick, +}; use super::user::{User, UserKey}; use crate::NaiaServerError; @@ -14,7 +17,10 @@ pub struct Events { errors: Vec, auths: HashMap>, messages: HashMap>>, - requests: HashMap>>, + requests: HashMap< + ChannelKind, + HashMap>, + >, spawns: Vec<(UserKey, E)>, despawns: Vec<(UserKey, E)>, publishes: Vec<(UserKey, E)>, @@ -82,7 +88,10 @@ impl Events { } pub fn take_requests( &mut self, - ) -> HashMap>> { + ) -> HashMap< + ChannelKind, + HashMap>, + > { mem::take(&mut self.requests) } diff --git a/server/src/lib.rs b/server/src/lib.rs index 3343eb64d..faa5ba87f 100644 --- a/server/src/lib.rs +++ b/server/src/lib.rs @@ -17,8 +17,9 @@ pub mod transport; pub mod shared { pub use naia_shared::{ default_channels, BigMap, BigMapKey, BitReader, BitWrite, BitWriter, ConstBitLength, - FileBitWriter, Random, Serde, SerdeErr, SignedInteger, SignedVariableInteger, SocketConfig, - UnsignedInteger, UnsignedVariableInteger, GlobalResponseId, ResponseReceiveKey, + FileBitWriter, GlobalResponseId, Random, ResponseReceiveKey, Serde, SerdeErr, + SignedInteger, SignedVariableInteger, SocketConfig, UnsignedInteger, + UnsignedVariableInteger, }; } pub mod internal { @@ -31,6 +32,7 @@ mod cache_map; mod connection; mod error; mod events; +mod request; mod room; mod server; mod server_config; @@ -38,15 +40,14 @@ mod time_manager; mod user; mod user_scope; mod world; -mod request; pub use connection::tick_buffer_messages::TickBufferMessages; pub use error::NaiaServerError; pub use events::{ AuthEvent, ConnectEvent, DelegateEntityEvent, DespawnEntityEvent, DisconnectEvent, EntityAuthGrantEvent, EntityAuthResetEvent, ErrorEvent, Events, InsertComponentEvent, - MessageEvent, PublishEntityEvent, RemoveComponentEvent, SpawnEntityEvent, TickEvent, - UnpublishEntityEvent, UpdateComponentEvent, RequestEvent, + MessageEvent, PublishEntityEvent, RemoveComponentEvent, RequestEvent, SpawnEntityEvent, + TickEvent, UnpublishEntityEvent, UpdateComponentEvent, }; pub use room::{RoomKey, RoomMut, RoomRef}; pub use server::Server; diff --git a/server/src/request.rs b/server/src/request.rs index 08ad18183..6ca8555f3 100644 --- a/server/src/request.rs +++ b/server/src/request.rs @@ -1,6 +1,8 @@ use std::collections::HashMap; -use naia_shared::{ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer}; +use naia_shared::{ + ChannelKind, GlobalRequestId, GlobalResponseId, LocalResponseId, MessageContainer, +}; use crate::UserKey; @@ -27,7 +29,10 @@ impl GlobalRequestManager { id } - pub(crate) fn destroy_request_id(&mut self, request_id: &GlobalRequestId) -> Option<(UserKey, MessageContainer)> { + pub(crate) fn destroy_request_id( + &mut self, + request_id: &GlobalRequestId, + ) -> Option<(UserKey, MessageContainer)> { let Some((_, response_opt)) = self.map.get(request_id) else { return None; }; @@ -38,7 +43,11 @@ impl GlobalRequestManager { return None; } - pub(crate) fn receive_response(&mut self, request_id: &GlobalRequestId, response: MessageContainer) { + pub(crate) fn receive_response( + &mut self, + request_id: &GlobalRequestId, + response: MessageContainer, + ) { let (_, response_opt) = self.map.get_mut(request_id).unwrap(); *response_opt = Some(response); } @@ -58,16 +67,31 @@ impl GlobalResponseManager { } } - pub(crate) fn create_response_id(&mut self, user_key: &UserKey, channel_kind: &ChannelKind, local_response_id: &LocalResponseId) -> GlobalResponseId { + pub(crate) fn create_response_id( + &mut self, + user_key: &UserKey, + channel_kind: &ChannelKind, + local_response_id: &LocalResponseId, + ) -> GlobalResponseId { let id = GlobalResponseId::new(self.next_id); self.next_id = self.next_id.wrapping_add(1); - self.map.insert(id, (user_key.clone(), channel_kind.clone(), local_response_id.clone())); + self.map.insert( + id, + ( + user_key.clone(), + channel_kind.clone(), + local_response_id.clone(), + ), + ); id } - pub(crate) fn destroy_response_id(&mut self, global_response_id: &GlobalResponseId) -> Option<(UserKey, ChannelKind, LocalResponseId)> { + pub(crate) fn destroy_response_id( + &mut self, + global_response_id: &GlobalResponseId, + ) -> Option<(UserKey, ChannelKind, LocalResponseId)> { self.map.remove(global_response_id) } -} \ No newline at end of file +} diff --git a/server/src/server.rs b/server/src/server.rs index 19786b135..6a07a78e3 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -1,16 +1,33 @@ use std::{ + any::Any, collections::{hash_set::Iter, HashMap, HashSet}, hash::Hash, net::SocketAddr, panic, time::Duration, - any::Any, }; use log::{info, warn}; -use naia_shared::{BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SerdeErr, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType}; +use naia_shared::{ + BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, + EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, + EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, + GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, + MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, Response, + ResponseReceiveKey, ResponseSendKey, Serde, SerdeErr, SharedGlobalWorldManager, SocketConfig, + StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType, +}; +use super::{ + error::NaiaServerError, + events::Events, + room::{Room, RoomKey, RoomMut, RoomRef}, + server_config::ServerConfig, + user::{User, UserKey, UserMut, UserRef}, + user_scope::{UserScopeMut, UserScopeRef}, +}; +use crate::world::entity_room_map::EntityRoomMap; use crate::{ connection::{ connection::Connection, @@ -18,6 +35,7 @@ use crate::{ io::Io, tick_buffer_messages::TickBufferMessages, }, + request::{GlobalRequestManager, GlobalResponseManager}, time_manager::TimeManager, transport::Socket, world::{ @@ -26,16 +44,6 @@ use crate::{ server_auth_handler::AuthOwner, }, ReplicationConfig, - request::{GlobalRequestManager, GlobalResponseManager}, -}; -use crate::world::entity_room_map::EntityRoomMap; -use super::{ - error::NaiaServerError, - events::Events, - room::{Room, RoomKey, RoomMut, RoomRef}, - server_config::ServerConfig, - user::{User, UserKey, UserMut, UserRef}, - user_scope::{UserScopeRef, UserScopeMut}, }; /// A server that uses either UDP or WebRTC communication to send/receive @@ -288,8 +296,11 @@ impl Server { } // - pub fn send_request(&mut self, user_key: &UserKey, request: &Q) -> Result, NaiaServerError> { - + pub fn send_request( + &mut self, + user_key: &UserKey, + request: &Q, + ) -> Result, NaiaServerError> { let cloned_request = Q::clone_box(request); let id = self.send_request_inner(user_key, &ChannelKind::of::(), cloned_request)?; Ok(ResponseReceiveKey::new(id)) @@ -301,7 +312,6 @@ impl Server { channel_kind: &ChannelKind, request_box: Box, ) -> Result { - let channel_settings = self.protocol.channel_kinds.channel(&channel_kind); if !channel_settings.can_request_and_respond() { @@ -316,7 +326,9 @@ impl Server { }; let Some(connection) = self.user_connections.get_mut(&user.address) else { warn!("currently not connected to user"); - return Err(NaiaServerError::Message("currently not connected to user".to_string())); + return Err(NaiaServerError::Message( + "currently not connected to user".to_string(), + )); }; let mut converter = EntityConverterMut::new( &self.global_world_manager, @@ -336,8 +348,11 @@ impl Server { } /// Sends a Response for a given Request. Returns whether or not was successful. - pub fn send_response(&mut self, response_key: &ResponseSendKey, response: &S) -> bool { - + pub fn send_response( + &mut self, + response_key: &ResponseSendKey, + response: &S, + ) -> bool { let response_id = response_key.response_id(); let cloned_response = S::clone_box(response); @@ -351,7 +366,10 @@ impl Server { response_id: &GlobalResponseId, response_box: Box, ) -> bool { - let Some((user_key, channel_kind, local_response_id)) = self.global_response_manager.destroy_response_id(&response_id) else { + let Some((user_key, channel_kind, local_response_id)) = self + .global_response_manager + .destroy_response_id(&response_id) + else { return false; }; let Some(user) = self.users.get(&user_key) else { @@ -375,9 +393,14 @@ impl Server { return true; } - pub fn receive_response(&mut self, response_key: &ResponseReceiveKey) -> Option<(UserKey, S)> { + pub fn receive_response( + &mut self, + response_key: &ResponseReceiveKey, + ) -> Option<(UserKey, S)> { let request_id = response_key.request_id(); - let Some((user_key, container)) = self.global_request_manager.destroy_request_id(&request_id) else { + let Some((user_key, container)) = + self.global_request_manager.destroy_request_id(&request_id) + else { return None; }; let response: S = Box::::downcast::(container.to_boxed_any()) @@ -696,7 +719,8 @@ impl Server { fn entity_enable_delegation_response(&mut self, user_key: &UserKey, entity: &E) { if self.global_world_manager.entity_is_delegated(entity) { - let Some(auth_status) = self.global_world_manager.entity_authority_status(entity) else { + let Some(auth_status) = self.global_world_manager.entity_authority_status(entity) + else { panic!("Entity should have an Auth status if it is delegated..") }; if auth_status != EntityAuthStatus::Available { @@ -1040,14 +1064,8 @@ impl Server { .insert(*user_key, *entity, is_contained); } - pub(crate) fn user_scope_has_entity( - &self, - user_key: &UserKey, - entity: &E, - ) -> bool { - if let Some(in_scope) = - self.entity_scope_map.get(user_key, entity) - { + pub(crate) fn user_scope_has_entity(&self, user_key: &UserKey, entity: &E) -> bool { + if let Some(in_scope) = self.entity_scope_map.get(user_key, entity) { *in_scope } else { false @@ -1202,7 +1220,10 @@ impl Server { // send publish message to entity owner let entity_owner = self.global_world_manager.entity_owner(&entity); let Some(EntityOwner::Client(user_key)) = entity_owner else { - panic!("Entity is not owned by a Client. Cannot publish entity. Owner is: {:?}", entity_owner); + panic!( + "Entity is not owned by a Client. Cannot publish entity. Owner is: {:?}", + entity_owner + ); }; let message = EntityEventMessage::new_publish(&self.global_world_manager, entity); self.send_message::(&user_key, &message); @@ -1282,7 +1303,10 @@ impl Server { panic!("entity should have an owner at this point"); }; let EntityOwner::ClientPublic(user_key) = entity_owner else { - panic!("entity should be owned by a public client at this point. Owner is: {:?}", entity_owner); + panic!( + "entity should be owned by a public client at this point. Owner is: {:?}", + entity_owner + ); }; self.global_world_manager.migrate_entity_to_server(&entity); @@ -1412,7 +1436,7 @@ impl Server { let Some(user) = self.users.get(user_key) else { panic!("Attempting to despawn entities for a nonexistent user"); }; - let Some (connection) = self.user_connections.get_mut(&user.address) else { + let Some(connection) = self.user_connections.get_mut(&user.address) else { panic!("Attempting to despawn entities on a nonexistent connection"); }; @@ -1626,7 +1650,9 @@ impl Server { continue; }; - let Ok(should_continue) = self.maintain_handshake(&address, &header, &mut reader) else { + let Ok(should_continue) = + self.maintain_handshake(&address, &header, &mut reader) + else { warn!("Server Error: cannot read malformed packet"); continue; }; diff --git a/server/src/world/entity_room_map.rs b/server/src/world/entity_room_map.rs index 309761ee3..ac29ee181 100644 --- a/server/src/world/entity_room_map.rs +++ b/server/src/world/entity_room_map.rs @@ -6,13 +6,13 @@ use std::{ use crate::RoomKey; pub struct EntityRoomMap { - map: HashMap> + map: HashMap>, } impl EntityRoomMap { pub fn new() -> Self { Self { - map: HashMap::new() + map: HashMap::new(), } } diff --git a/server/src/world/mod.rs b/server/src/world/mod.rs index f3d5f0a58..ebb87c89b 100644 --- a/server/src/world/mod.rs +++ b/server/src/world/mod.rs @@ -1,10 +1,10 @@ pub mod entity_mut; pub mod entity_owner; pub mod entity_ref; +pub mod entity_room_map; pub mod entity_scope_map; pub mod global_entity_record; pub mod global_world_manager; pub mod mut_channel; pub mod replication_config; pub mod server_auth_handler; -pub mod entity_room_map; diff --git a/shared/derive/src/message.rs b/shared/derive/src/message.rs index 681100a1b..bbab3d2f0 100644 --- a/shared/derive/src/message.rs +++ b/shared/derive/src/message.rs @@ -1,6 +1,9 @@ use proc_macro2::{Span, TokenStream}; use quote::{format_ident, quote}; -use syn::{parse_macro_input, Data, DeriveInput, Fields, Ident, Index, LitStr, Member, Type, Generics, GenericParam}; +use syn::{ + parse_macro_input, Data, DeriveInput, Fields, GenericParam, Generics, Ident, Index, LitStr, + Member, Type, +}; use super::shared::{get_builder_generic_fields, get_generics, get_struct_type, StructType}; @@ -19,7 +22,15 @@ pub fn message_impl( // Names let struct_name = input.ident; - let struct_name_str = LitStr::new(format!("{}{}", &struct_name.to_string(), &untyped_generics.to_string()).as_str(), struct_name.span()); + let struct_name_str = LitStr::new( + format!( + "{}{}", + &struct_name.to_string(), + &untyped_generics.to_string() + ) + .as_str(), + struct_name.span(), + ); let lowercase_struct_name = Ident::new( struct_name.to_string().to_lowercase().as_str(), Span::call_site(), @@ -35,8 +46,14 @@ pub fn message_impl( let bit_length_method = get_bit_length_method(&fields, &struct_type); let write_method = get_write_method(&fields, &struct_type); let builder_create_method = get_builder_create_method(&builder_name, &turbofish); - let builder_new_method = get_builder_new_method(&typed_generics, &builder_name, &untyped_generics, &input.generics); - let builder_read_method = get_builder_read_method(&struct_name, &fields, &struct_type, &turbofish); + let builder_new_method = get_builder_new_method( + &typed_generics, + &builder_name, + &untyped_generics, + &input.generics, + ); + let builder_read_method = + get_builder_read_method(&struct_name, &fields, &struct_type, &turbofish); let is_fragment_method = get_is_fragment_method(is_fragment); let is_request_method = get_is_request_method(is_request); @@ -389,7 +406,6 @@ fn get_bit_length_method(fields: &[Field], struct_type: &StructType) -> TokenStr } pub fn get_builder_create_method(builder_name: &Ident, turbofish: &TokenStream) -> TokenStream { - let builder_new = quote! { #builder_name #turbofish::new() }; @@ -482,7 +498,6 @@ pub fn get_builder_new_method( untyped_generics: &TokenStream, input_generics: &Generics, ) -> TokenStream { - let fn_impl = if input_generics.gt_token.is_none() { quote! { return Self; } } else { @@ -493,7 +508,8 @@ pub fn get_builder_new_method( panic!("Only type parameters are supported for now"); }; - let field_name = format_ident!("phantom_{}", type_param.ident.to_string().to_lowercase()); + let field_name = + format_ident!("phantom_{}", type_param.ident.to_string().to_lowercase()); let new_output_right = quote! { #field_name: std::marker::PhantomData, }; diff --git a/shared/derive/src/replicate.rs b/shared/derive/src/replicate.rs index a8b40075e..38d1fc66a 100644 --- a/shared/derive/src/replicate.rs +++ b/shared/derive/src/replicate.rs @@ -5,7 +5,10 @@ use syn::{ PathArguments, Type, }; -use crate::{message::get_builder_new_method, shared::{get_struct_type, StructType, get_generics, get_builder_generic_fields}}; +use crate::{ + message::get_builder_new_method, + shared::{get_builder_generic_fields, get_generics, get_struct_type, StructType}, +}; const UNNAMED_FIELD_PREFIX: &'static str = "unnamed_field_"; @@ -47,7 +50,15 @@ pub fn replicate_impl( // Names let replica_name = input.ident.clone(); - let replica_name_str = LitStr::new(format!("{}{}", &replica_name.to_string(), &untyped_generics.to_string()).as_str(), replica_name.span()); + let replica_name_str = LitStr::new( + format!( + "{}{}", + &replica_name.to_string(), + &untyped_generics.to_string() + ) + .as_str(), + replica_name.span(), + ); let lowercase_replica_name = Ident::new( replica_name.to_string().to_lowercase().as_str(), Span::call_site(), @@ -69,17 +80,24 @@ pub fn replicate_impl( }; // Methods - let new_complete_method = - get_new_complete_method(&enum_name, &properties, &struct_type); + let new_complete_method = get_new_complete_method(&enum_name, &properties, &struct_type); let builder_create_method = get_builder_create_method(&builder_name, &turbofish); - let builder_new_method = get_builder_new_method(&typed_generics, &builder_name, &untyped_generics, &input.generics); - let builder_read_method = get_builder_read_method(&replica_name, &properties, &struct_type, &turbofish); - let read_create_update_method = get_read_create_update_method(&replica_name, &properties, &untyped_generics); + let builder_new_method = get_builder_new_method( + &typed_generics, + &builder_name, + &untyped_generics, + &input.generics, + ); + let builder_read_method = + get_builder_read_method(&replica_name, &properties, &struct_type, &turbofish); + let read_create_update_method = + get_read_create_update_method(&replica_name, &properties, &untyped_generics); let dyn_ref_method = get_dyn_ref_method(); let dyn_mut_method = get_dyn_mut_method(); let clone_method = get_clone_method(&properties, &struct_type); - let mirror_method = get_mirror_method(&replica_name, &properties, &struct_type, &untyped_generics); + let mirror_method = + get_mirror_method(&replica_name, &properties, &struct_type, &untyped_generics); let set_mutator_method = get_set_mutator_method(&properties, &struct_type); let publish_method = get_publish_method(&enum_name, &properties, &struct_type); let unpublish_method = get_unpublish_method(&properties, &struct_type); @@ -94,7 +112,8 @@ pub fn replicate_impl( let write_update_method = get_write_update_method(&enum_name, &properties, &struct_type); let relations_waiting_method = get_relations_waiting_method(&properties, &struct_type); let relations_complete_method = get_relations_complete_method(&properties, &struct_type); - let split_update_method = get_split_update_method(&replica_name, &properties, &untyped_generics); + let split_update_method = + get_split_update_method(&replica_name, &properties, &untyped_generics); let gen = quote! { mod #module_name { @@ -391,10 +410,7 @@ pub fn get_dyn_mut_method() -> TokenStream { } } -fn get_clone_method( - properties: &[Property], - struct_type: &StructType, -) -> TokenStream { +fn get_clone_method(properties: &[Property], struct_type: &StructType) -> TokenStream { let mut output = quote! {}; let mut entity_property_output = quote! {}; @@ -757,7 +773,6 @@ pub fn get_new_complete_method( } pub fn get_builder_create_method(builder_name: &Ident, turbofish: &TokenStream) -> TokenStream { - let builder_new = quote! { #builder_name #turbofish::new() }; @@ -850,7 +865,11 @@ pub fn get_builder_read_method( } } -pub fn get_read_create_update_method(replica_name: &Ident, properties: &[Property], untyped_generics: &TokenStream) -> TokenStream { +pub fn get_read_create_update_method( + replica_name: &Ident, + properties: &[Property], + untyped_generics: &TokenStream, +) -> TokenStream { let mut prop_read_writes = quote! {}; for property in properties.iter() { let new_output_right = match property { @@ -903,7 +922,11 @@ pub fn get_read_create_update_method(replica_name: &Ident, properties: &[Propert } } -fn get_split_update_method(replica_name: &Ident, properties: &[Property], untyped_generics: &TokenStream) -> TokenStream { +fn get_split_update_method( + replica_name: &Ident, + properties: &[Property], + untyped_generics: &TokenStream, +) -> TokenStream { let mut output = quote! {}; for property in properties.iter() { diff --git a/shared/derive/src/shared.rs b/shared/derive/src/shared.rs index b0c62d678..e9a2eb4f2 100644 --- a/shared/derive/src/shared.rs +++ b/shared/derive/src/shared.rs @@ -67,4 +67,4 @@ pub fn get_builder_generic_fields(generics: &Generics) -> TokenStream { quote! { { #output } } -} \ No newline at end of file +} diff --git a/shared/serde/src/impls.rs b/shared/serde/src/impls.rs index 1243442a8..8504c9e07 100644 --- a/shared/serde/src/impls.rs +++ b/shared/serde/src/impls.rs @@ -2,8 +2,8 @@ mod array; mod boxed; mod hash; mod option; +mod phantom; mod scalars; mod string; mod tuple; mod vector; -mod phantom; diff --git a/shared/serde/src/impls/phantom.rs b/shared/serde/src/impls/phantom.rs index 0dcaa97c7..2644ca32d 100644 --- a/shared/serde/src/impls/phantom.rs +++ b/shared/serde/src/impls/phantom.rs @@ -31,8 +31,8 @@ impl ConstBitLength for PhantomData { #[cfg(test)] mod phantom_tests { - use std::marker::PhantomData; use crate::{bit_reader::BitReader, bit_writer::BitWriter, serde::Serde}; + use std::marker::PhantomData; #[test] fn read_write() { @@ -52,4 +52,4 @@ mod phantom_tests { assert_eq!(in_phantom, out_phantom); } -} \ No newline at end of file +} diff --git a/shared/src/lib.rs b/shared/src/lib.rs index fdce250d6..31b420dd1 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -24,13 +24,13 @@ pub use naia_derive::{ Channel, Message, MessageBevy, MessageHecs, Replicate, ReplicateBevy, ReplicateHecs, }; pub use naia_serde::{ - BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, MTU_SIZE_BITS, MTU_SIZE_BYTES, - OutgoingPacket, OwnedBitReader, Serde, SerdeBevyClient, SerdeBevyServer, SerdeBevyShared, - SerdeErr, SerdeHecs, SerdeIntegerConversion, SerdeInternal, SignedInteger, - SignedVariableInteger, UnsignedInteger, UnsignedVariableInteger, + BitReader, BitWrite, BitWriter, ConstBitLength, FileBitWriter, OutgoingPacket, OwnedBitReader, + Serde, SerdeBevyClient, SerdeBevyServer, SerdeBevyShared, SerdeErr, SerdeHecs, + SerdeIntegerConversion, SerdeInternal, SignedInteger, SignedVariableInteger, UnsignedInteger, + UnsignedVariableInteger, MTU_SIZE_BITS, MTU_SIZE_BYTES, }; pub use naia_socket_shared::{ - Instant, link_condition_logic, LinkConditionerConfig, Random, SocketConfig, TimeQueue, + link_condition_logic, Instant, LinkConditionerConfig, Random, SocketConfig, TimeQueue, }; mod backends; @@ -81,7 +81,9 @@ pub use messages::{ message_kinds::{MessageKind, MessageKinds}, message_manager::MessageManager, named::Named, - request::{Request, Response, ResponseReceiveKey, ResponseSendKey, GlobalResponseId, GlobalRequestId}, + request::{ + GlobalRequestId, GlobalResponseId, Request, Response, ResponseReceiveKey, ResponseSendKey, + }, }; pub use world::{ component::{ @@ -135,9 +137,11 @@ pub use world::{ }; pub use bigmap::{BigMap, BigMapKey}; -pub use game_time::{GAME_TIME_LIMIT, GameDuration, GameInstant}; +pub use game_time::{GameDuration, GameInstant, GAME_TIME_LIMIT}; pub use key_generator::KeyGenerator; -pub use messages::channels::senders::request_sender::{LocalRequestOrResponseId, RequestOrResponse}; +pub use messages::channels::senders::request_sender::{ + LocalRequestOrResponseId, RequestOrResponse, +}; pub use protocol::{Protocol, ProtocolPlugin}; pub use types::{HostType, MessageIndex, PacketIndex, ShortMessageIndex, Tick}; pub use wrapping_number::{sequence_greater_than, sequence_less_than, wrapping_diff}; diff --git a/shared/src/messages/channels/receivers/channel_receiver.rs b/shared/src/messages/channels/receivers/channel_receiver.rs index c233291cd..044a9f891 100644 --- a/shared/src/messages/channels/receivers/channel_receiver.rs +++ b/shared/src/messages/channels/receivers/channel_receiver.rs @@ -1,7 +1,11 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, messages::{message_container::MessageContainer, message_kinds::MessageKinds}, world::remote::entity_waitlist::EntityWaitlist}; use crate::messages::channels::senders::request_sender::LocalRequestId; +use crate::{ + messages::{message_container::MessageContainer, message_kinds::MessageKinds}, + world::remote::entity_waitlist::EntityWaitlist, + LocalEntityAndGlobalEntityConverter, LocalResponseId, +}; pub trait ChannelReceiver

: Send + Sync { /// Read messages from an internal buffer and return their content @@ -23,5 +27,10 @@ pub trait MessageChannelReceiver: ChannelReceiver { reader: &mut BitReader, ) -> Result<(), SerdeErr>; - fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>); + fn receive_requests_and_responses( + &mut self, + ) -> ( + Vec<(LocalResponseId, MessageContainer)>, + Vec<(LocalRequestId, MessageContainer)>, + ); } diff --git a/shared/src/messages/channels/receivers/fragment_receiver.rs b/shared/src/messages/channels/receivers/fragment_receiver.rs index 44ff6098e..3fc6de138 100644 --- a/shared/src/messages/channels/receivers/fragment_receiver.rs +++ b/shared/src/messages/channels/receivers/fragment_receiver.rs @@ -26,7 +26,6 @@ impl FragmentReceiver { converter: &dyn LocalEntityAndGlobalEntityConverter, message: MessageContainer, ) -> Option { - if !message.is_fragment() { panic!("Received non-fragmented message in FragmentReceiver!"); } diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index fcbd76c0e..fe57c3c6e 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -1,15 +1,23 @@ use naia_serde::{BitReader, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, messages::{ - channels::{receivers::{ - channel_receiver::{ChannelReceiver, MessageChannelReceiver}, - fragment_receiver::FragmentReceiver, - indexed_message_reader::IndexedMessageReader, - reliable_receiver::ReliableReceiver, - }, senders::request_sender::LocalRequestOrResponseId}, - message_kinds::MessageKinds, -}, RequestOrResponse, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; use crate::messages::channels::senders::request_sender::LocalRequestId; +use crate::{ + messages::{ + channels::{ + receivers::{ + channel_receiver::{ChannelReceiver, MessageChannelReceiver}, + fragment_receiver::FragmentReceiver, + indexed_message_reader::IndexedMessageReader, + reliable_receiver::ReliableReceiver, + }, + senders::request_sender::LocalRequestOrResponseId, + }, + message_kinds::MessageKinds, + }, + types::MessageIndex, + world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, + LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, RequestOrResponse, +}; // Receiver Arranger Trait pub trait ReceiverArranger: Send + Sync { @@ -105,7 +113,7 @@ impl ReliableMessageReceiver { &mut self, message_kinds: &MessageKinds, converter: &dyn LocalEntityAndGlobalEntityConverter, - message_container: MessageContainer + message_container: MessageContainer, ) { // look at message, see if it's a request or response if message_container.is_request_or_response() { @@ -128,8 +136,7 @@ impl ReliableMessageReceiver { LocalRequestOrResponseId::Request(local_request_id) => { let request = request_or_response; let local_response_id = local_request_id.receive_from_remote(); - self.incoming_requests - .push((local_response_id, request)); + self.incoming_requests.push((local_response_id, request)); } LocalRequestOrResponseId::Response(local_response_id) => { let response = request_or_response; @@ -181,7 +188,15 @@ impl MessageChannelReceiver for ReliableMessageReceiver Ok(()) } - fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { - (std::mem::take(&mut self.incoming_requests), std::mem::take(&mut self.incoming_responses)) + fn receive_requests_and_responses( + &mut self, + ) -> ( + Vec<(LocalResponseId, MessageContainer)>, + Vec<(LocalRequestId, MessageContainer)>, + ) { + ( + std::mem::take(&mut self.incoming_requests), + std::mem::take(&mut self.incoming_responses), + ) } } diff --git a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs index cd674b46c..ae3298225 100644 --- a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs @@ -2,14 +2,20 @@ use std::mem; use naia_serde::{BitReader, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, messages::{ - channels::{receivers::{ - channel_receiver::{ChannelReceiver, MessageChannelReceiver}, - indexed_message_reader::IndexedMessageReader, - }}, - message_kinds::MessageKinds, -}, sequence_greater_than, types::MessageIndex, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; use crate::messages::channels::senders::request_sender::LocalRequestId; +use crate::{ + messages::{ + channels::receivers::{ + channel_receiver::{ChannelReceiver, MessageChannelReceiver}, + indexed_message_reader::IndexedMessageReader, + }, + message_kinds::MessageKinds, + }, + sequence_greater_than, + types::MessageIndex, + world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, + LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, +}; pub struct SequencedUnreliableReceiver { newest_received_message_index: Option, @@ -92,7 +98,12 @@ impl MessageChannelReceiver for SequencedUnreliableReceiver { Ok(()) } - fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { + fn receive_requests_and_responses( + &mut self, + ) -> ( + Vec<(LocalResponseId, MessageContainer)>, + Vec<(LocalRequestId, MessageContainer)>, + ) { panic!("SequencedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs index 190b70f6b..fa1d6c85c 100644 --- a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs @@ -2,11 +2,15 @@ use std::{collections::VecDeque, mem}; use naia_serde::{BitReader, Serde, SerdeErr}; -use crate::{LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, messages::{ - channels::{receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}}, - message_kinds::MessageKinds, -}, world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}}; use crate::messages::channels::senders::request_sender::LocalRequestId; +use crate::{ + messages::{ + channels::receivers::channel_receiver::{ChannelReceiver, MessageChannelReceiver}, + message_kinds::MessageKinds, + }, + world::remote::entity_waitlist::{EntityWaitlist, WaitlistStore}, + LocalEntityAndGlobalEntityConverter, LocalResponseId, MessageContainer, +}; pub struct UnorderedUnreliableReceiver { incoming_messages: VecDeque, @@ -80,7 +84,12 @@ impl MessageChannelReceiver for UnorderedUnreliableReceiver { Ok(()) } - fn receive_requests_and_responses(&mut self) -> (Vec<(LocalResponseId, MessageContainer)>, Vec<(LocalRequestId, MessageContainer)>) { + fn receive_requests_and_responses( + &mut self, + ) -> ( + Vec<(LocalResponseId, MessageContainer)>, + Vec<(LocalRequestId, MessageContainer)>, + ) { panic!("UnorderedUnreliable channels do not support requests"); } } diff --git a/shared/src/messages/channels/senders/channel_sender.rs b/shared/src/messages/channels/senders/channel_sender.rs index e8d35a850..ed9ed1cb9 100644 --- a/shared/src/messages/channels/senders/channel_sender.rs +++ b/shared/src/messages/channels/senders/channel_sender.rs @@ -1,9 +1,13 @@ use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{messages::{message_container::MessageContainer, message_kinds::MessageKinds}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, LocalResponseId}; use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::messages::request::GlobalRequestId; +use crate::{ + messages::{message_container::MessageContainer, message_kinds::MessageKinds}, + types::MessageIndex, + LocalEntityAndGlobalEntityConverterMut, LocalResponseId, +}; pub trait ChannelSender

: Send + Sync { /// Queues a Message to be transmitted to the remote host into an internal buffer @@ -27,11 +31,26 @@ pub trait MessageChannelSender: ChannelSender { ) -> Option>; /// Queues a Request to be transmitted to the remote host into an internal buffer - fn send_outgoing_request(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, global_request_id: GlobalRequestId, request: MessageContainer); + fn send_outgoing_request( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + global_request_id: GlobalRequestId, + request: MessageContainer, + ); /// Queues a Response to be transmitted to the remote host into an internal buffer - fn send_outgoing_response(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, local_response_id: LocalResponseId, response: MessageContainer); + fn send_outgoing_response( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + local_response_id: LocalResponseId, + response: MessageContainer, + ); /// Request is finished, so clean up the local request id and return the global request id - fn process_incoming_response(&mut self, local_request_id: &LocalRequestId) -> Option; + fn process_incoming_response( + &mut self, + local_request_id: &LocalRequestId, + ) -> Option; } diff --git a/shared/src/messages/channels/senders/mod.rs b/shared/src/messages/channels/senders/mod.rs index 0024dbac8..1f595ec7a 100644 --- a/shared/src/messages/channels/senders/mod.rs +++ b/shared/src/messages/channels/senders/mod.rs @@ -1,8 +1,8 @@ pub mod channel_sender; pub mod indexed_message_writer; pub mod message_fragmenter; -pub mod reliable_sender; pub mod reliable_message_sender; +pub mod reliable_sender; +pub mod request_sender; pub mod sequenced_unreliable_sender; pub mod unordered_unreliable_sender; -pub mod request_sender; diff --git a/shared/src/messages/channels/senders/reliable_message_sender.rs b/shared/src/messages/channels/senders/reliable_message_sender.rs index 49b09af5d..b5de297f6 100644 --- a/shared/src/messages/channels/senders/reliable_message_sender.rs +++ b/shared/src/messages/channels/senders/reliable_message_sender.rs @@ -1,17 +1,20 @@ - use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{LocalEntityAndGlobalEntityConverterMut, LocalResponseId, messages::{ - channels::senders::{ - channel_sender::{ChannelSender, MessageChannelSender}, - indexed_message_writer::IndexedMessageWriter, - }, - message_container::MessageContainer, - message_kinds::MessageKinds, -}, ReliableSender, types::MessageIndex}; use crate::messages::channels::senders::request_sender::{LocalRequestId, RequestSender}; use crate::messages::request::GlobalRequestId; +use crate::{ + messages::{ + channels::senders::{ + channel_sender::{ChannelSender, MessageChannelSender}, + indexed_message_writer::IndexedMessageWriter, + }, + message_container::MessageContainer, + message_kinds::MessageKinds, + }, + types::MessageIndex, + LocalEntityAndGlobalEntityConverterMut, LocalResponseId, ReliableSender, +}; // Sender pub struct ReliableMessageSender { @@ -68,7 +71,7 @@ impl MessageChannelSender for ReliableMessageSender { message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, global_request_id: GlobalRequestId, - request: MessageContainer + request: MessageContainer, ) { let processed_request = self.request_sender.process_outgoing_request( message_kinds, @@ -79,7 +82,13 @@ impl MessageChannelSender for ReliableMessageSender { self.send_message(processed_request); } - fn send_outgoing_response(&mut self, message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, local_response_id: LocalResponseId, response: MessageContainer) { + fn send_outgoing_response( + &mut self, + message_kinds: &MessageKinds, + converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, + local_response_id: LocalResponseId, + response: MessageContainer, + ) { let processed_response = self.request_sender.process_outgoing_response( message_kinds, converter, @@ -89,7 +98,11 @@ impl MessageChannelSender for ReliableMessageSender { self.send_message(processed_response); } - fn process_incoming_response(&mut self, local_request_id: &LocalRequestId) -> Option { - self.request_sender.process_incoming_response(local_request_id) + fn process_incoming_response( + &mut self, + local_request_id: &LocalRequestId, + ) -> Option { + self.request_sender + .process_incoming_response(local_request_id) } } diff --git a/shared/src/messages/channels/senders/reliable_sender.rs b/shared/src/messages/channels/senders/reliable_sender.rs index 81d1ce04f..0dea52536 100644 --- a/shared/src/messages/channels/senders/reliable_sender.rs +++ b/shared/src/messages/channels/senders/reliable_sender.rs @@ -2,10 +2,7 @@ use std::{collections::VecDeque, mem, time::Duration}; use naia_socket_shared::Instant; -use crate::{messages:: - channels::senders:: - channel_sender::ChannelSender, - types::MessageIndex}; +use crate::{messages::channels::senders::channel_sender::ChannelSender, types::MessageIndex}; // Sender pub struct ReliableSender { @@ -114,4 +111,4 @@ impl ChannelSender

for ReliableSender

{ fn notify_message_delivered(&mut self, message_index: &MessageIndex) { self.deliver_message(message_index); } -} \ No newline at end of file +} diff --git a/shared/src/messages/channels/senders/request_sender.rs b/shared/src/messages/channels/senders/request_sender.rs index ae56d881b..15f804c86 100644 --- a/shared/src/messages/channels/senders/request_sender.rs +++ b/shared/src/messages/channels/senders/request_sender.rs @@ -1,10 +1,10 @@ -use std::{time::Duration, collections::HashMap}; +use std::{collections::HashMap, time::Duration}; use naia_derive::MessageRequest; use naia_serde::{BitWriter, SerdeInternal}; -use crate::{KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKinds}; use crate::messages::request::GlobalRequestId; +use crate::{KeyGenerator, LocalEntityAndGlobalEntityConverterMut, MessageContainer, MessageKinds}; pub struct RequestSender { local_key_generator: KeyGenerator, @@ -24,11 +24,11 @@ impl RequestSender { message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, global_request_id: GlobalRequestId, - request: MessageContainer + request: MessageContainer, ) -> MessageContainer { - let local_request_id = self.local_key_generator.generate(); - self.local_to_global_ids.insert(local_request_id, global_request_id); + self.local_to_global_ids + .insert(local_request_id, global_request_id); let mut writer = BitWriter::with_max_capacity(); request.write(message_kinds, &mut writer, converter); @@ -42,9 +42,8 @@ impl RequestSender { message_kinds: &MessageKinds, converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, local_response_id: LocalResponseId, - response: MessageContainer + response: MessageContainer, ) -> MessageContainer { - let mut writer = BitWriter::with_max_capacity(); response.write(message_kinds, &mut writer, converter); let response_bytes = writer.to_bytes(); @@ -52,7 +51,10 @@ impl RequestSender { MessageContainer::from_write(Box::new(response_message), converter) } - pub(crate) fn process_incoming_response(&mut self, local_request_id: &LocalRequestId) -> Option { + pub(crate) fn process_incoming_response( + &mut self, + local_request_id: &LocalRequestId, + ) -> Option { self.local_key_generator.recycle_key(local_request_id); self.local_to_global_ids.remove(local_request_id) } @@ -108,7 +110,9 @@ impl LocalRequestOrResponseId { pub fn to_request_id(&self) -> LocalRequestId { match self { LocalRequestOrResponseId::Request(id) => *id, - LocalRequestOrResponseId::Response(_) => panic!("LocalRequestOrResponseId is a response"), + LocalRequestOrResponseId::Response(_) => { + panic!("LocalRequestOrResponseId is a response") + } } } @@ -160,4 +164,4 @@ impl LocalResponseId { pub fn receive_from_remote(&self) -> LocalRequestId { LocalRequestId { id: self.id } } -} \ No newline at end of file +} diff --git a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs index c2c8a04ae..70d45070d 100644 --- a/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/sequenced_unreliable_sender.rs @@ -3,16 +3,20 @@ use std::collections::VecDeque; use naia_serde::BitWriter; use naia_socket_shared::Instant; -use crate::{messages::{ - channels::senders::{ - channel_sender::{ChannelSender, MessageChannelSender}, - indexed_message_writer::IndexedMessageWriter, - }, - message_container::MessageContainer, - message_kinds::MessageKinds, -}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, LocalResponseId}; use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::messages::request::GlobalRequestId; +use crate::{ + messages::{ + channels::senders::{ + channel_sender::{ChannelSender, MessageChannelSender}, + indexed_message_writer::IndexedMessageWriter, + }, + message_container::MessageContainer, + message_kinds::MessageKinds, + }, + types::MessageIndex, + LocalEntityAndGlobalEntityConverterMut, LocalResponseId, +}; pub struct SequencedUnreliableSender { /// Buffer of the next messages to send along with their MessageKind @@ -69,11 +73,23 @@ impl MessageChannelSender for SequencedUnreliableSender { ) } - fn send_outgoing_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + fn send_outgoing_request( + &mut self, + _: &MessageKinds, + _: &mut dyn LocalEntityAndGlobalEntityConverterMut, + _: GlobalRequestId, + _: MessageContainer, + ) { panic!("SequencedUnreliable channel does not support requests"); } - fn send_outgoing_response(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: LocalResponseId, _: MessageContainer) { + fn send_outgoing_response( + &mut self, + _: &MessageKinds, + _: &mut dyn LocalEntityAndGlobalEntityConverterMut, + _: LocalResponseId, + _: MessageContainer, + ) { panic!("SequencedUnreliable channel does not support requests"); } diff --git a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs index ee4a690fe..5ea7563c7 100644 --- a/shared/src/messages/channels/senders/unordered_unreliable_sender.rs +++ b/shared/src/messages/channels/senders/unordered_unreliable_sender.rs @@ -3,13 +3,17 @@ use std::collections::VecDeque; use naia_serde::{BitWrite, BitWriter, Serde}; use naia_socket_shared::Instant; -use crate::{messages::{ - channels::senders::channel_sender::{ChannelSender, MessageChannelSender}, - message_container::MessageContainer, - message_kinds::MessageKinds, -}, types::MessageIndex, LocalEntityAndGlobalEntityConverterMut, LocalResponseId}; use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::messages::request::GlobalRequestId; +use crate::{ + messages::{ + channels::senders::channel_sender::{ChannelSender, MessageChannelSender}, + message_container::MessageContainer, + message_kinds::MessageKinds, + }, + types::MessageIndex, + LocalEntityAndGlobalEntityConverterMut, LocalResponseId, +}; pub struct UnorderedUnreliableSender { outgoing_messages: VecDeque, @@ -102,7 +106,13 @@ impl MessageChannelSender for UnorderedUnreliableSender { None } - fn send_outgoing_request(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: GlobalRequestId, _: MessageContainer) { + fn send_outgoing_request( + &mut self, + _: &MessageKinds, + _: &mut dyn LocalEntityAndGlobalEntityConverterMut, + _: GlobalRequestId, + _: MessageContainer, + ) { panic!("UnorderedUnreliable channel does not support requests"); } @@ -110,7 +120,13 @@ impl MessageChannelSender for UnorderedUnreliableSender { panic!("UnorderedUnreliable channel does not support requests"); } - fn send_outgoing_response(&mut self, _: &MessageKinds, _: &mut dyn LocalEntityAndGlobalEntityConverterMut, _: LocalResponseId, _: MessageContainer) { + fn send_outgoing_response( + &mut self, + _: &MessageKinds, + _: &mut dyn LocalEntityAndGlobalEntityConverterMut, + _: LocalResponseId, + _: MessageContainer, + ) { panic!("UnorderedUnreliable channel does not support requests"); } } diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index c8b6ec26f..8fa79d732 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -3,33 +3,39 @@ use std::{collections::HashMap, hash::Hash}; use naia_serde::{BitReader, BitWrite, BitWriter, ConstBitLength, Serde, SerdeErr}; use naia_socket_shared::Instant; -use crate::{constants::FRAGMENTATION_LIMIT_BITS, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, messages::{ - request::GlobalRequestId, - channels::{ - channel::ChannelMode, - channel::ChannelSettings, - channel_kinds::{ChannelKind, ChannelKinds}, - receivers::{ - channel_receiver::MessageChannelReceiver, - ordered_reliable_receiver::OrderedReliableReceiver, - sequenced_reliable_receiver::SequencedReliableReceiver, - sequenced_unreliable_receiver::SequencedUnreliableReceiver, - unordered_reliable_receiver::UnorderedReliableReceiver, - unordered_unreliable_receiver::UnorderedUnreliableReceiver, - }, - senders::{ - request_sender::LocalResponseId, - channel_sender::MessageChannelSender, - message_fragmenter::MessageFragmenter, reliable_message_sender::ReliableMessageSender, - sequenced_unreliable_sender::SequencedUnreliableSender, - unordered_unreliable_sender::UnorderedUnreliableSender, +use crate::{ + constants::FRAGMENTATION_LIMIT_BITS, + messages::{ + channels::{ + channel::ChannelMode, + channel::ChannelSettings, + channel_kinds::{ChannelKind, ChannelKinds}, + receivers::{ + channel_receiver::MessageChannelReceiver, + ordered_reliable_receiver::OrderedReliableReceiver, + sequenced_reliable_receiver::SequencedReliableReceiver, + sequenced_unreliable_receiver::SequencedUnreliableReceiver, + unordered_reliable_receiver::UnorderedReliableReceiver, + unordered_unreliable_receiver::UnorderedUnreliableReceiver, + }, + senders::{ + channel_sender::MessageChannelSender, message_fragmenter::MessageFragmenter, + reliable_message_sender::ReliableMessageSender, request_sender::LocalResponseId, + sequenced_unreliable_sender::SequencedUnreliableSender, + unordered_unreliable_sender::UnorderedUnreliableSender, + }, }, + message_container::MessageContainer, + request::GlobalRequestId, + }, + types::{HostType, MessageIndex, PacketIndex}, + world::{ + entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, + remote::entity_waitlist::EntityWaitlist, }, - message_container::MessageContainer, -}, Protocol, types::{HostType, MessageIndex, PacketIndex}, world::{ - entity::entity_converters::LocalEntityAndGlobalEntityConverterMut, - remote::entity_waitlist::EntityWaitlist, -}}; + EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityConverter, MessageKinds, + Protocol, +}; /// Handles incoming/outgoing messages, tracks the delivery status of Messages /// so that guaranteed Messages can be re-transmitted to the remote host @@ -77,9 +83,7 @@ impl MessageManager { | ChannelMode::OrderedReliable(settings) => { channel_senders.insert( channel_kind, - Box::new(ReliableMessageSender::new( - settings.rtt_resend_factor, - )), + Box::new(ReliableMessageSender::new(settings.rtt_resend_factor)), ); } ChannelMode::TickBuffered(_) => { @@ -197,7 +201,7 @@ impl MessageManager { converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, channel_kind: &ChannelKind, global_request_id: GlobalRequestId, - request: MessageContainer + request: MessageContainer, ) { let Some(channel) = self.channel_senders.get_mut(channel_kind) else { panic!("Channel not configured correctly! Cannot send message."); @@ -211,7 +215,7 @@ impl MessageManager { converter: &mut dyn LocalEntityAndGlobalEntityConverterMut, channel_kind: &ChannelKind, local_response_id: LocalResponseId, - response: MessageContainer + response: MessageContainer, ) { let Some(channel) = self.channel_senders.get_mut(channel_kind) else { panic!("Channel not configured correctly! Cannot send message."); @@ -329,7 +333,8 @@ impl MessageManager { let mut output = Vec::new(); // TODO: shouldn't we have a priority mechanisms between channels? for (channel_kind, channel) in &mut self.channel_receivers { - let messages = channel.receive_messages(message_kinds, entity_waitlist, &entity_converter); + let messages = + channel.receive_messages(message_kinds, entity_waitlist, &entity_converter); output.push((channel_kind.clone(), messages)); } output @@ -338,12 +343,19 @@ impl MessageManager { /// Retrieve all requests from the channel buffers pub fn receive_requests_and_responses( &mut self, - ) -> (Vec<(ChannelKind, Vec<(LocalResponseId, MessageContainer)>)>, Vec<(GlobalRequestId, MessageContainer)>) { + ) -> ( + Vec<(ChannelKind, Vec<(LocalResponseId, MessageContainer)>)>, + Vec<(GlobalRequestId, MessageContainer)>, + ) { let mut request_output = Vec::new(); let mut response_output = Vec::new(); for (channel_kind, channel) in &mut self.channel_receivers { - - if !self.channel_settings.get(channel_kind).unwrap().can_request_and_respond() { + if !self + .channel_settings + .get(channel_kind) + .unwrap() + .can_request_and_respond() + { continue; } @@ -354,10 +366,15 @@ impl MessageManager { if !responses.is_empty() { let Some(channel_sender) = self.channel_senders.get_mut(channel_kind) else { - panic!("Channel not configured correctly! Cannot send message on channel: {:?}", channel_kind); + panic!( + "Channel not configured correctly! Cannot send message on channel: {:?}", + channel_kind + ); }; for (local_request_id, response) in responses { - let global_request_id = channel_sender.process_incoming_response(&local_request_id).unwrap(); + let global_request_id = channel_sender + .process_incoming_response(&local_request_id) + .unwrap(); response_output.push((global_request_id, response)); } } diff --git a/shared/src/messages/mod.rs b/shared/src/messages/mod.rs index 843c866da..d64d9717d 100644 --- a/shared/src/messages/mod.rs +++ b/shared/src/messages/mod.rs @@ -9,5 +9,3 @@ pub mod request; #[cfg(test)] mod tests; - - diff --git a/shared/src/messages/request.rs b/shared/src/messages/request.rs index 5db4cbbd1..a9b7c8312 100644 --- a/shared/src/messages/request.rs +++ b/shared/src/messages/request.rs @@ -8,8 +8,7 @@ pub trait Request: Message { } // Response -pub trait Response: Message { -} +pub trait Response: Message {} // ResponseSendKey #[derive(Clone, Eq, PartialEq, Hash)] @@ -58,9 +57,7 @@ pub struct GlobalRequestId { impl GlobalRequestId { pub fn new(id: u64) -> Self { - Self { - id, - } + Self { id } } } @@ -71,8 +68,6 @@ pub struct GlobalResponseId { impl GlobalResponseId { pub fn new(id: u64) -> Self { - Self { - id, - } + Self { id } } -} \ No newline at end of file +} diff --git a/shared/src/messages/tests/fragment.rs b/shared/src/messages/tests/fragment.rs index 3cfc3f04b..aa6851254 100644 --- a/shared/src/messages/tests/fragment.rs +++ b/shared/src/messages/tests/fragment.rs @@ -70,7 +70,10 @@ fn convert_single_fragment() { let Some(incoming_message_container) = incoming_message_container_opt else { panic!("Did not receive reassembled message!"); }; - let Ok(incoming_message) = incoming_message_container.to_boxed_any().downcast::() else { + let Ok(incoming_message) = incoming_message_container + .to_boxed_any() + .downcast::() + else { panic!("cannot cast message container into proper message!"); }; @@ -122,7 +125,10 @@ fn convert_multiple_fragments() { let Some(incoming_message_container) = incoming_message_container_opt else { panic!("Did not receive reassembled message!"); }; - let Ok(incoming_message) = incoming_message_container.to_boxed_any().downcast::() else { + let Ok(incoming_message) = incoming_message_container + .to_boxed_any() + .downcast::() + else { panic!("cannot cast message container into proper message!"); }; diff --git a/shared/src/protocol.rs b/shared/src/protocol.rs index 1fdad59ee..15e661e25 100644 --- a/shared/src/protocol.rs +++ b/shared/src/protocol.rs @@ -2,17 +2,22 @@ use std::time::Duration; use naia_socket_shared::{LinkConditionerConfig, SocketConfig}; -use crate::{connection::compression_config::CompressionConfig, messages::{ - channels::{ - channel::{Channel, ChannelDirection, ChannelMode, ChannelSettings}, - channel_kinds::ChannelKinds, - default_channels::DefaultChannelsPlugin, - system_channel::SystemChannel, +use crate::{ + connection::compression_config::CompressionConfig, + messages::{ + channels::{ + channel::{Channel, ChannelDirection, ChannelMode, ChannelSettings}, + channel_kinds::ChannelKinds, + default_channels::DefaultChannelsPlugin, + system_channel::SystemChannel, + }, + fragment::FragmentedMessage, + message::Message, + message_kinds::MessageKinds, }, - fragment::FragmentedMessage, - message::Message, - message_kinds::MessageKinds, -}, world::component::{component_kinds::ComponentKinds, replicate::Replicate}, EntityEventMessage, ReliableSettings, Request, RequestOrResponse}; + world::component::{component_kinds::ComponentKinds, replicate::Replicate}, + EntityEventMessage, ReliableSettings, Request, RequestOrResponse, +}; // Protocol Plugin pub trait ProtocolPlugin { diff --git a/shared/src/types.rs b/shared/src/types.rs index 7d116bc7b..437db17b3 100644 --- a/shared/src/types.rs +++ b/shared/src/types.rs @@ -7,4 +7,4 @@ pub type ShortMessageIndex = u8; pub enum HostType { Server, Client, -} \ No newline at end of file +} diff --git a/shared/src/world/entity/entity_converters.rs b/shared/src/world/entity/entity_converters.rs index 39c5c9c1a..41178d11c 100644 --- a/shared/src/world/entity/entity_converters.rs +++ b/shared/src/world/entity/entity_converters.rs @@ -322,7 +322,8 @@ impl<'a, 'b, E: Copy + Eq + Hash> LocalEntityAndGlobalEntityConverterMut ) -> Result { let Ok(entity) = self .global_world_manager - .global_entity_to_entity(global_entity) else { + .global_entity_to_entity(global_entity) + else { return Err(EntityDoesNotExistError); }; if !self diff --git a/shared/src/world/local_entity_map.rs b/shared/src/world/local_entity_map.rs index 94bac13f7..5374198c6 100644 --- a/shared/src/world/local_entity_map.rs +++ b/shared/src/world/local_entity_map.rs @@ -143,8 +143,8 @@ impl LocalEntityMap { }; if record.host.is_some() && record.remote.is_some() { let Some(remote_entity) = record.remote.take() else { - panic!("record does not have remote entity"); - }; + panic!("record does not have remote entity"); + }; self.remote_to_world.remove(&remote_entity); return remote_entity; } else { diff --git a/shared/src/world/remote/remote_world_manager.rs b/shared/src/world/remote/remote_world_manager.rs index be0964019..5a03083b6 100644 --- a/shared/src/world/remote/remote_world_manager.rs +++ b/shared/src/world/remote/remote_world_manager.rs @@ -311,7 +311,8 @@ impl RemoteWorldManager { // split the component_update into the waiting and ready parts let Ok((waiting_updates_opt, ready_update_opt)) = - component_update.split_into_waiting_and_ready(&converter, component_kinds) else { + component_update.split_into_waiting_and_ready(&converter, component_kinds) + else { warn!("Remote World Manager: cannot read malformed component update message"); continue; }; From ea039a7e6b52921bdedceccc48133c1a72579a25 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 26 Feb 2024 20:13:04 -0600 Subject: [PATCH 41/99] expose ResponseSendKey --- adapters/bevy/client/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index c579f4797..994d44e65 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -1,5 +1,5 @@ pub use naia_bevy_shared::{ - sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, Timer, + sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, Timer, ResponseSendKey, }; pub use naia_client::{ shared::{default_channels, Instant, Message, ResponseReceiveKey}, From 8c4245d07c7df2e43ee72b92266ee4f5d3d441fa Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 26 Feb 2024 21:23:59 -0600 Subject: [PATCH 42/99] exposing a whether or not PropertyMutate is successful --- shared/src/world/component/entity_property.rs | 10 ++++++---- shared/src/world/component/property.rs | 6 +++--- shared/src/world/component/property_mutate.rs | 2 +- shared/src/world/host/entity_channel.rs | 13 +++++++++--- shared/src/world/host/mut_channel.rs | 5 +++-- shared/src/world/host/world_channel.rs | 20 ++++++++++++------- 6 files changed, 36 insertions(+), 20 deletions(-) diff --git a/shared/src/world/component/entity_property.rs b/shared/src/world/component/entity_property.rs index 924568d1a..238c776c7 100644 --- a/shared/src/world/component/entity_property.rs +++ b/shared/src/world/component/entity_property.rs @@ -802,9 +802,11 @@ impl HostOwnedRelation { } fn mutate(&mut self) { - if let Some(mutator) = &mut self.mutator { - mutator.mutate(self.index); - } + let _success = if let Some(mutator) = &mut self.mutator { + mutator.mutate(self.index) + } else { + false + }; } } @@ -1086,7 +1088,7 @@ impl DelegatedRelation { if !self.can_mutate() { panic!("Must request authority to mutate a Delegated EntityProperty."); } - self.mutator.mutate(self.index); + let _success = self.mutator.mutate(self.index); } fn can_mutate(&self) -> bool { diff --git a/shared/src/world/component/property.rs b/shared/src/world/component/property.rs index ea24a96a9..b67292415 100644 --- a/shared/src/world/component/property.rs +++ b/shared/src/world/component/property.rs @@ -382,7 +382,7 @@ impl HostOwnedProperty { warn!("Host Property should have a mutator immediately after creation."); return; }; - mutator.mutate(self.index); + let _success = mutator.mutate(self.index); } } @@ -447,7 +447,7 @@ impl RemotePublicProperty { } fn mutate(&mut self) { - self.mutator.mutate(self.index); + let _success = self.mutator.mutate(self.index); } } @@ -504,7 +504,7 @@ impl DelegatedProperty { if !self.can_mutate() { panic!("Must request authority to mutate a Delegated Property."); } - self.mutator.mutate(self.index); + let _success = self.mutator.mutate(self.index); } fn can_mutate(&self) -> bool { diff --git a/shared/src/world/component/property_mutate.rs b/shared/src/world/component/property_mutate.rs index 2e3559263..fb324564a 100644 --- a/shared/src/world/component/property_mutate.rs +++ b/shared/src/world/component/property_mutate.rs @@ -5,7 +5,7 @@ use std::ops::{Deref, DerefMut}; pub trait PropertyMutate: PropertyMutateClone + Send + Sync + 'static { /// Given the index of the Property whose value has changed, queue that /// Property for transmission to the Client - fn mutate(&mut self, property_index: u8); + fn mutate(&mut self, property_index: u8) -> bool; } pub trait PropertyMutateClone { diff --git a/shared/src/world/host/entity_channel.rs b/shared/src/world/host/entity_channel.rs index 8370cb36b..9f0dfdd54 100644 --- a/shared/src/world/host/entity_channel.rs +++ b/shared/src/world/host/entity_channel.rs @@ -94,18 +94,24 @@ impl EntityChannel { self.despawn_after_spawned = true; } - // returns true if entity should be immediately despawned - pub(crate) fn spawning_complete(&mut self) -> bool { + // returns (if entity should be immediately despawned, if release message should be sent) + pub(crate) fn spawning_complete(&mut self) -> (bool, bool) { if self.state != EntityChannelState::Spawning { panic!("EntityChannel::spawning_complete() called on non-spawning entity"); } self.state = EntityChannelState::Spawned; + let mut release_message_queued = false; + if self.ready_to_release() && self.release_auth == ReleaseAuthState::Waiting { + self.release_auth = ReleaseAuthState::Complete; + release_message_queued = true; + } + if self.components.len() > 0 { panic!("Newly spawned entity should not have any components yet.."); } - return self.despawn_after_spawned; + return (self.despawn_after_spawned, release_message_queued); } pub(crate) fn despawn(&mut self) { @@ -196,6 +202,7 @@ impl EntityChannel { return false; } + // // returns whether auth release message should be sent pub(crate) fn release_authority(&mut self) -> bool { if self.ready_to_release() { self.release_auth = ReleaseAuthState::Complete; diff --git a/shared/src/world/host/mut_channel.rs b/shared/src/world/host/mut_channel.rs index a32f360b6..19cfcf794 100644 --- a/shared/src/world/host/mut_channel.rs +++ b/shared/src/world/host/mut_channel.rs @@ -118,8 +118,9 @@ impl MutSender { } impl PropertyMutate for MutSender { - fn mutate(&mut self, property_index: u8) { - self.channel.send(property_index); + fn mutate(&mut self, property_index: u8) -> bool { + let success = self.channel.send(property_index); + success } } diff --git a/shared/src/world/host/world_channel.rs b/shared/src/world/host/world_channel.rs index d5efa696d..44f8400ed 100644 --- a/shared/src/world/host/world_channel.rs +++ b/shared/src/world/host/world_channel.rs @@ -325,7 +325,11 @@ impl WorldChannel { if !entity_channel.is_spawning() { panic!("World Channel: should only receive this event if entity channel is spawning"); } - let should_despawn = entity_channel.spawning_complete(); + + let (should_despawn, should_send_release_message) = entity_channel.spawning_complete(); + if should_send_release_message { + self.outgoing_release_auth_messages.push(*entity); + } self.remote_world.insert(*entity, CheckedSet::new()); @@ -602,12 +606,14 @@ impl WorldChannel { for (entity, entity_channel) in self.entity_channels.iter() { if entity_channel.is_spawned() && world.has_entity(entity) { for component_kind in entity_channel.inserted_components() { - if global_world_manager.entity_is_replicating(entity) - && !self - .diff_handler - .diff_mask_is_clear(entity, &component_kind) - && world.has_component_of_kind(entity, &component_kind) - { + if self + .diff_handler + .diff_mask_is_clear(entity, &component_kind) { + continue; + } + let entity_is_replicating = global_world_manager.entity_is_replicating(entity); + let world_has_component = world.has_component_of_kind(entity, &component_kind); + if entity_is_replicating && world_has_component { if !output.contains_key(entity) { output.insert(*entity, HashSet::new()); } From 3489a766f6f5e66979a4ed15118bfef01227b472 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 29 Feb 2024 15:04:18 -0600 Subject: [PATCH 43/99] fix typo in defining the limit of fragments for a message --- shared/src/messages/fragment.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/shared/src/messages/fragment.rs b/shared/src/messages/fragment.rs index 45d70dea1..81f0fb7e8 100644 --- a/shared/src/messages/fragment.rs +++ b/shared/src/messages/fragment.rs @@ -2,9 +2,9 @@ use naia_derive::MessageFragment; use naia_serde::{BitReader, BitWrite, ConstBitLength, Serde, SerdeErr, UnsignedInteger}; const FRAGMENT_ID_BITS: u8 = 10; -const FRAGMENT_ID_LIMIT: u16 = 2 ^ (FRAGMENT_ID_BITS as u16); +const FRAGMENT_ID_LIMIT: u16 = 2.pow(FRAGMENT_ID_BITS as u16); const FRAGMENT_INDEX_BITS: u8 = 20; -const FRAGMENT_INDEX_LIMIT: u32 = 2 ^ (FRAGMENT_INDEX_BITS as u32); +const FRAGMENT_INDEX_LIMIT: u32 = 2.pow(FRAGMENT_INDEX_BITS as u32); // FragmentId #[derive(Copy, Clone, PartialEq, Eq, Hash)] From 6937ab1d9ab2aafcb35d4e9c35216ca0c1b38b1b Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 29 Feb 2024 15:12:48 -0600 Subject: [PATCH 44/99] remove unused debug statement --- shared/src/messages/channels/receivers/fragment_receiver.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shared/src/messages/channels/receivers/fragment_receiver.rs b/shared/src/messages/channels/receivers/fragment_receiver.rs index 3fc6de138..1053941d9 100644 --- a/shared/src/messages/channels/receivers/fragment_receiver.rs +++ b/shared/src/messages/channels/receivers/fragment_receiver.rs @@ -38,7 +38,7 @@ impl FragmentReceiver { let fragment_id = fragment.id(); let fragment_index = fragment.index(); let fragment_total = fragment.total().as_usize(); - info!("fragment_total: {fragment_total}"); + // info!("fragment_total: {fragment_total}"); if !self.map.contains_key(&fragment_id) { self.map .insert(fragment_id, (0, vec![Box::new([]); fragment_total])); From f436df47e7cce50b94177c15403a8d34c9937e6f Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 3 Mar 2024 17:34:23 -0600 Subject: [PATCH 45/99] cargo fmt --- adapters/bevy/client/src/lib.rs | 3 ++- .../src/messages/channels/receivers/fragment_receiver.rs | 2 -- shared/src/messages/fragment.rs | 4 ++-- shared/src/world/host/world_channel.rs | 5 +++-- socket/shared/src/link_conditioner_config.rs | 8 ++++++++ 5 files changed, 15 insertions(+), 7 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 994d44e65..4245b96a9 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -1,5 +1,6 @@ pub use naia_bevy_shared::{ - sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, Tick, Timer, ResponseSendKey, + sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, ResponseSendKey, + Tick, Timer, }; pub use naia_client::{ shared::{default_channels, Instant, Message, ResponseReceiveKey}, diff --git a/shared/src/messages/channels/receivers/fragment_receiver.rs b/shared/src/messages/channels/receivers/fragment_receiver.rs index 1053941d9..89d35f0ef 100644 --- a/shared/src/messages/channels/receivers/fragment_receiver.rs +++ b/shared/src/messages/channels/receivers/fragment_receiver.rs @@ -1,7 +1,5 @@ use std::collections::HashMap; -use log::info; - use naia_serde::BitReader; use crate::{ diff --git a/shared/src/messages/fragment.rs b/shared/src/messages/fragment.rs index 81f0fb7e8..35c13c7ac 100644 --- a/shared/src/messages/fragment.rs +++ b/shared/src/messages/fragment.rs @@ -2,9 +2,9 @@ use naia_derive::MessageFragment; use naia_serde::{BitReader, BitWrite, ConstBitLength, Serde, SerdeErr, UnsignedInteger}; const FRAGMENT_ID_BITS: u8 = 10; -const FRAGMENT_ID_LIMIT: u16 = 2.pow(FRAGMENT_ID_BITS as u16); +const FRAGMENT_ID_LIMIT: u16 = 2_u16.pow(FRAGMENT_ID_BITS as u32); const FRAGMENT_INDEX_BITS: u8 = 20; -const FRAGMENT_INDEX_LIMIT: u32 = 2.pow(FRAGMENT_INDEX_BITS as u32); +const FRAGMENT_INDEX_LIMIT: u32 = 2_u32.pow(FRAGMENT_INDEX_BITS as u32); // FragmentId #[derive(Copy, Clone, PartialEq, Eq, Hash)] diff --git a/shared/src/world/host/world_channel.rs b/shared/src/world/host/world_channel.rs index 44f8400ed..583c17380 100644 --- a/shared/src/world/host/world_channel.rs +++ b/shared/src/world/host/world_channel.rs @@ -608,8 +608,9 @@ impl WorldChannel { for component_kind in entity_channel.inserted_components() { if self .diff_handler - .diff_mask_is_clear(entity, &component_kind) { - continue; + .diff_mask_is_clear(entity, &component_kind) + { + continue; } let entity_is_replicating = global_world_manager.entity_is_replicating(entity); let world_has_component = world.has_component_of_kind(entity, &component_kind); diff --git a/socket/shared/src/link_conditioner_config.rs b/socket/shared/src/link_conditioner_config.rs index b6c96df21..6a041d01f 100644 --- a/socket/shared/src/link_conditioner_config.rs +++ b/socket/shared/src/link_conditioner_config.rs @@ -22,6 +22,14 @@ impl LinkConditionerConfig { } } + pub fn perfect_condition() -> Self { + LinkConditionerConfig { + incoming_latency: 1, + incoming_jitter: 0, + incoming_loss: 0.0, + } + } + /// Creates a new LinkConditioner that simulates a connection which is in a /// good condition pub fn good_condition() -> Self { From 686375b3931e6907636cea69f6511beb4048c291 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 22 Mar 2024 20:36:38 -0500 Subject: [PATCH 46/99] Random struct shouldn't have a struct body --- socket/shared/src/backends/miniquad/random.rs | 2 +- socket/shared/src/backends/native/random.rs | 2 +- socket/shared/src/backends/wasm_bindgen/random.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/socket/shared/src/backends/miniquad/random.rs b/socket/shared/src/backends/miniquad/random.rs index b6120d504..44227cf7a 100644 --- a/socket/shared/src/backends/miniquad/random.rs +++ b/socket/shared/src/backends/miniquad/random.rs @@ -4,7 +4,7 @@ extern "C" { /// Container for cross-platform Random methods -pub struct Random {} +pub struct Random; impl Random { /// returns a random f32 value between an upper & lower bound diff --git a/socket/shared/src/backends/native/random.rs b/socket/shared/src/backends/native/random.rs index d528d8bc2..bd224f18b 100644 --- a/socket/shared/src/backends/native/random.rs +++ b/socket/shared/src/backends/native/random.rs @@ -2,7 +2,7 @@ use rand::Rng; /// Container for cross-platform Random methods -pub struct Random {} +pub struct Random; impl Random { /// returns a random f32 value between an upper & lower bound diff --git a/socket/shared/src/backends/wasm_bindgen/random.rs b/socket/shared/src/backends/wasm_bindgen/random.rs index 6ac386a3d..9da861aa9 100644 --- a/socket/shared/src/backends/wasm_bindgen/random.rs +++ b/socket/shared/src/backends/wasm_bindgen/random.rs @@ -2,7 +2,7 @@ use js_sys::Math::random; /// Container for cross-platform Random methods -pub struct Random {} +pub struct Random; impl Random { /// returns a random f32 value between an upper & lower bound From 0b2c36cf6e89cf967530ed2c66973e0a1bb0d8d5 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 18 Apr 2024 16:11:56 -0500 Subject: [PATCH 47/99] adding some optional logging to server socket session handler --- socket/server/src/session.rs | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/socket/server/src/session.rs b/socket/server/src/session.rs index bdc05fae4..3f0284fa9 100644 --- a/socket/server/src/session.rs +++ b/socket/server/src/session.rs @@ -79,11 +79,13 @@ async fn serve(mut session_endpoint: SessionEndpoint, mut stream: Arc = None; - let mut rtc_url_match = false; + let mut rtc_url_matched = false; let mut body: Vec = Vec::new(); + // info!("Incoming WebRTC session request from {}", remote_addr); + let buf_reader = BufReader::new(stream.clone()); let mut bytes = buf_reader.bytes(); { @@ -91,11 +93,12 @@ async fn serve(mut session_endpoint: SessionEndpoint, mut stream: Arc= content_length { + // info!("read body finished"); success = true; break; } @@ -112,20 +115,27 @@ async fn serve(mut session_endpoint: SessionEndpoint, mut stream: Arc().ok(); + // info!("read content length: {:?}", content_length); } else if str.is_empty() { - headers_read = true; + // info!("read headers finished"); + headers_been_read = true; + } else { + // info!("read leftover line 1: {}", str); } } else if str.starts_with( RTC_URL_PATH .get() .expect("unable to retrieve URL path, was it not configured?"), ) { - rtc_url_match = true; + // info!("starting to match to RTC URL"); + rtc_url_matched = true; + } else { + // info!("read leftover line 2: {}", str); } } else { line.push(byte); @@ -167,6 +177,8 @@ async fn serve(mut session_endpoint: SessionEndpoint, mut stream: Arc Date: Sat, 20 Apr 2024 19:08:51 -0500 Subject: [PATCH 48/99] added additional logging for handshake failures --- .idea/.gitignore | 2 ++ server/src/connection/handshake_manager.rs | 6 ++++++ shared/src/world/component/entity_property.rs | 1 + 3 files changed, 9 insertions(+) diff --git a/.idea/.gitignore b/.idea/.gitignore index 13566b81b..a9d7db9c0 100644 --- a/.idea/.gitignore +++ b/.idea/.gitignore @@ -6,3 +6,5 @@ # Datasource local storage ignored files /dataSources/ /dataSources.local.xml +# GitHub Copilot persisted chat sessions +/copilot/chatSessions diff --git a/server/src/connection/handshake_manager.rs b/server/src/connection/handshake_manager.rs index fe8dc93e8..e8fd35a84 100644 --- a/server/src/connection/handshake_manager.rs +++ b/server/src/connection/handshake_manager.rs @@ -1,5 +1,7 @@ use std::{collections::HashMap, hash::Hash, net::SocketAddr}; +use log::warn; + use ring::{hmac, rand}; pub use naia_shared::{ @@ -76,13 +78,16 @@ impl HandshakeManager { // Verify that timestamp hash has been written by this // server instance let Some(timestamp) = self.timestamp_validate(reader) else { + warn!("Handshake Error from {}: Invalid timestamp hash", address); return HandshakeResult::Invalid; }; // Timestamp hash is validated, now start configured auth process let Ok(has_auth) = bool::de(reader) else { + warn!("Handshake Error from {}: Auth flag serde issue", address); return HandshakeResult::Invalid; }; if has_auth != self.require_auth { + warn!("Handshake Error from {}: Auth flag mismatch", address); return HandshakeResult::Invalid; } @@ -93,6 +98,7 @@ impl HandshakeManager { } let Ok(auth_message) = message_kinds.read(reader, &FakeEntityConverter) else { + warn!("Handshake Error from {}: Auth message serde issue", address); return HandshakeResult::Invalid; }; diff --git a/shared/src/world/component/entity_property.rs b/shared/src/world/component/entity_property.rs index 238c776c7..675c6c5fd 100644 --- a/shared/src/world/component/entity_property.rs +++ b/shared/src/world/component/entity_property.rs @@ -463,6 +463,7 @@ impl EntityProperty { Some(global_entity) } else { panic!("Error completing waiting EntityProperty! Could not convert RemoteEntity to GlobalEntity!"); + // I hit this 2 times } }; From 799b5fa3fd4ef5079b62e3c95dae4d35b3937964 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 20 Apr 2024 19:47:39 -0500 Subject: [PATCH 49/99] remove auth from handshake, starting refactor to handle auth during http signaling --- client/src/client.rs | 7 ++-- client/src/connection/handshake_manager.rs | 25 ++---------- server/src/connection/handshake_manager.rs | 30 +++----------- server/src/server.rs | 47 +++++++--------------- test/tests/handshake.rs | 23 +++-------- 5 files changed, 33 insertions(+), 99 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index 2d7078fc2..21cc0d6ed 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -35,6 +35,7 @@ pub struct Client { client_config: ClientConfig, protocol: Protocol, // Connection + auth_message: Option, io: Io, server_connection: Option>, handshake_manager: HandshakeManager, @@ -67,6 +68,7 @@ impl Client { client_config: client_config.clone(), protocol, // Connection + auth_message: None, io: Io::new( &client_config.connection.bandwidth_measure_duration, &compression_config, @@ -86,8 +88,7 @@ impl Client { /// Set the auth object to use when setting up a connection with the Server pub fn auth(&mut self, auth: M) { - self.handshake_manager - .set_auth_message(MessageContainer::from_write( + self.auth_message = Some(MessageContainer::from_write( Box::new(auth), &mut FakeEntityConverter, )); @@ -258,7 +259,7 @@ impl Client { } } else { self.handshake_manager - .send(&self.protocol.message_kinds, &mut self.io); + .send(&mut self.io); } if let Some(events) = response_events { diff --git a/client/src/connection/handshake_manager.rs b/client/src/connection/handshake_manager.rs index ae81c4fc0..a89f67646 100644 --- a/client/src/connection/handshake_manager.rs +++ b/client/src/connection/handshake_manager.rs @@ -3,7 +3,7 @@ use std::time::Duration; use log::warn; use naia_shared::{ - BitReader, BitWriter, FakeEntityConverter, MessageContainer, MessageKinds, PacketType, Serde, + BitReader, BitWriter, PacketType, Serde, StandardHeader, Timer, Timestamp as stamp_time, }; @@ -52,7 +52,6 @@ pub struct HandshakeManager { handshake_timer: Timer, pre_connection_timestamp: Timestamp, pre_connection_digest: Option>, - auth_message: Option, } impl HandshakeManager { @@ -67,22 +66,17 @@ impl HandshakeManager { pre_connection_timestamp, pre_connection_digest: None, connection_state: HandshakeState::AwaitingChallengeResponse, - auth_message: None, ping_interval, handshake_pings, } } - pub fn set_auth_message(&mut self, auth: MessageContainer) { - self.auth_message = Some(auth); - } - pub fn is_connected(&self) -> bool { self.connection_state == HandshakeState::Connected } // Give handshake manager the opportunity to send out messages to the server - pub fn send(&mut self, message_kinds: &MessageKinds, io: &mut Io) { + pub fn send(&mut self, io: &mut Io) { if io.is_loaded() { if !self.handshake_timer.ringing() { return; @@ -99,7 +93,7 @@ impl HandshakeManager { } } HandshakeState::AwaitingValidateResponse => { - let writer = self.write_validate_request(message_kinds); + let writer = self.write_validate_request(); if io.send_packet(writer.to_packet()).is_err() { // TODO: pass this on and handle above warn!("Client Error: Cannot send validate request packet to Server"); @@ -215,7 +209,7 @@ impl HandshakeManager { } // Step 3 of Handshake - pub fn write_validate_request(&self, message_kinds: &MessageKinds) -> BitWriter { + pub fn write_validate_request(&self) -> BitWriter { let mut writer = BitWriter::new(); StandardHeader::new(PacketType::ClientValidateRequest, 0, 0, 0).ser(&mut writer); @@ -223,17 +217,6 @@ impl HandshakeManager { // write timestamp & digest into payload self.write_signed_timestamp(&mut writer); - // write auth message if there is one - if let Some(auth_message) = &self.auth_message { - // write that we have auth - true.ser(&mut writer); - // write payload - auth_message.write(message_kinds, &mut writer, &mut FakeEntityConverter); - } else { - // write that we do not have auth - false.ser(&mut writer); - } - writer } diff --git a/server/src/connection/handshake_manager.rs b/server/src/connection/handshake_manager.rs index e8fd35a84..4923fa617 100644 --- a/server/src/connection/handshake_manager.rs +++ b/server/src/connection/handshake_manager.rs @@ -5,7 +5,7 @@ use log::warn; use ring::{hmac, rand}; pub use naia_shared::{ - BitReader, BitWriter, FakeEntityConverter, MessageContainer, MessageKinds, PacketType, Serde, + BitReader, BitWriter, PacketType, Serde, SerdeErr, StandardHeader, }; @@ -15,24 +15,22 @@ pub type Timestamp = u64; pub enum HandshakeResult { Invalid, - Success(Option), + Success, } pub struct HandshakeManager { connection_hash_key: hmac::Key, - require_auth: bool, address_to_timestamp_map: HashMap, timestamp_digest_map: CacheMap>, } impl HandshakeManager { - pub fn new(require_auth: bool) -> Self { + pub fn new() -> Self { let connection_hash_key = hmac::Key::generate(hmac::HMAC_SHA256, &rand::SystemRandom::new()).unwrap(); Self { connection_hash_key, - require_auth, address_to_timestamp_map: HashMap::new(), timestamp_digest_map: CacheMap::with_capacity(64), } @@ -71,7 +69,6 @@ impl HandshakeManager { // Step 3 of Handshake pub fn recv_validate_request( &mut self, - message_kinds: &MessageKinds, address: &SocketAddr, reader: &mut BitReader, ) -> HandshakeResult { @@ -81,28 +78,11 @@ impl HandshakeManager { warn!("Handshake Error from {}: Invalid timestamp hash", address); return HandshakeResult::Invalid; }; - // Timestamp hash is validated, now start configured auth process - let Ok(has_auth) = bool::de(reader) else { - warn!("Handshake Error from {}: Auth flag serde issue", address); - return HandshakeResult::Invalid; - }; - if has_auth != self.require_auth { - warn!("Handshake Error from {}: Auth flag mismatch", address); - return HandshakeResult::Invalid; - } + // Timestamp hash is valid self.address_to_timestamp_map.insert(*address, timestamp); - if !has_auth { - return HandshakeResult::Success(None); - } - - let Ok(auth_message) = message_kinds.read(reader, &FakeEntityConverter) else { - warn!("Handshake Error from {}: Auth message serde issue", address); - return HandshakeResult::Invalid; - }; - - return HandshakeResult::Success(Some(auth_message)); + return HandshakeResult::Success; } // Step 4 of Handshake diff --git a/server/src/server.rs b/server/src/server.rs index 6a07a78e3..21872f28a 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -99,7 +99,7 @@ impl Server { heartbeat_timer: Timer::new(server_config.connection.heartbeat_interval), timeout_timer: Timer::new(server_config.connection.disconnection_timeout_duration), ping_timer: Timer::new(server_config.ping.ping_interval), - handshake_manager: HandshakeManager::new(server_config.require_auth), + handshake_manager: HandshakeManager::new(), // Users users: BigMap::new(), user_connections: HashMap::new(), @@ -159,7 +159,18 @@ impl Server { /// Accepts an incoming Client User, allowing them to establish a connection /// with the Server - pub fn accept_connection(&mut self, user_key: &UserKey) { + pub fn accept_connection(&mut self, _user_key: &UserKey) { + todo!(); + } + + /// Rejects an incoming Client User, terminating their attempt to establish + /// a connection with the Server + pub fn reject_connection(&mut self, _user_key: &UserKey) { + todo!(); + self.user_delete(_user_key); + } + + fn validate_connection(&mut self, user_key: &UserKey) { let Some(user) = self.users.get(user_key) else { warn!("unknown user is finalizing connection..."); return; @@ -217,28 +228,6 @@ impl Server { self.incoming_events.push_connection(user_key); } - /// Rejects an incoming Client User, terminating their attempt to establish - /// a connection with the Server - pub fn reject_connection(&mut self, user_key: &UserKey) { - if let Some(user) = self.users.get(user_key) { - // send connect reject response - let writer = self.handshake_manager.write_reject_response(); - if self - .io - .send_packet(&user.address, writer.to_packet()) - .is_err() - { - // TODO: pass this on and handle above - warn!( - "Server Error: Cannot send auth rejection packet to {}", - &user.address - ); - } - // - } - self.user_delete(user_key); - } - // Messages /// Queues up an Message to be sent to the Client associated with a given @@ -1708,11 +1697,10 @@ impl Server { } PacketType::ClientValidateRequest => { match self.handshake_manager.recv_validate_request( - &self.protocol.message_kinds, address, reader, ) { - HandshakeResult::Success(auth_message_opt) => { + HandshakeResult::Success => { if self.validated_users.contains_key(address) { // send validate response let writer = self.handshake_manager.write_validate_response(); @@ -1723,12 +1711,7 @@ impl Server { } else { let user = User::new(*address); let user_key = self.users.insert(user); - - if let Some(auth_message) = auth_message_opt { - self.incoming_events.push_auth(&user_key, auth_message); - } else { - self.accept_connection(&user_key); - } + self.validate_connection(&user_key); } } HandshakeResult::Invalid => { diff --git a/test/tests/handshake.rs b/test/tests/handshake.rs index 795cb8684..b8f2d13d4 100644 --- a/test/tests/handshake.rs +++ b/test/tests/handshake.rs @@ -11,7 +11,7 @@ use naia_test::Auth; #[test] fn end_to_end_handshake_w_auth() { let mut client = ClientHandshakeManager::new(Duration::new(0, 0), Duration::new(0, 0), 1); - let mut server = ServerHandshakeManager::new(true); + let mut server = ServerHandshakeManager::new(); let mut bytes: Box<[u8]>; let mut writer: BitWriter; let mut reader: BitReader; @@ -58,7 +58,7 @@ fn end_to_end_handshake_w_auth() { // 5. Client send connect request { - writer = client.write_validate_request(&message_kinds); + writer = client.write_validate_request(); bytes = writer.to_bytes(); } @@ -67,22 +67,9 @@ fn end_to_end_handshake_w_auth() { reader = BitReader::new(&bytes); StandardHeader::de(&mut reader).expect("unable to read standard header from stream"); let address = "127.0.0.1:4000".parse().unwrap(); - let result = server.recv_validate_request(&message_kinds, &address, &mut reader); - if let HandshakeResult::Success(Some(auth_message)) = result { - let boxed_any = auth_message.to_boxed_any(); - let auth_replica = boxed_any - .downcast_ref::() - .expect("did not construct protocol correctly..."); - assert_eq!( - auth_replica.username, username, - "Server received an invalid username: '{}', should be: '{}'", - auth_replica.username, username - ); - assert_eq!( - auth_replica.password, password, - "Server received an invalid password: '{}', should be: '{}'", - auth_replica.password, password - ); + let result = server.recv_validate_request(&address, &mut reader); + if let HandshakeResult::Success = result { + // } else { assert!(false, "handshake result from server was not correct"); } From 467259284024ed7e023b598f2f0128a402ee2c97 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 20 Apr 2024 20:38:05 -0500 Subject: [PATCH 50/99] client socket now can connect to the server socket with an optional auth payload in bytes .. this is transmitted to the server during the signal exchange via the Authorization header --- socket/client/Cargo.toml | 1 + .../src/backends/miniquad/naia_socket.js | 7 ++-- socket/client/src/backends/miniquad/shared.rs | 2 +- socket/client/src/backends/miniquad/socket.rs | 36 ++++++++++++++++++- socket/client/src/backends/native/socket.rs | 28 +++++++++++++-- socket/client/src/backends/socket.rs | 5 +++ .../src/backends/wasm_bindgen/data_channel.rs | 15 +++++++- .../src/backends/wasm_bindgen/socket.rs | 36 +++++++++++++++++-- 8 files changed, 120 insertions(+), 10 deletions(-) diff --git a/socket/client/Cargo.toml b/socket/client/Cargo.toml index 7232369e3..78e6876cc 100644 --- a/socket/client/Cargo.toml +++ b/socket/client/Cargo.toml @@ -32,6 +32,7 @@ web_sys = { version = "0.3.64", package = "web-sys", features = [ "XmlHttpRequest", "XmlHttpRequestEventTarget", "MessageEvent", "ProgressEvent", "ErrorEvent", "Blob" ], optional = true } tinyjson = { version = "2.3", optional = true } miniquad = { version = "0.3", features = ["log-impl"], optional = true } +base64 = { version = "0.13" } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] webrtc-unreliable-client = { path = "../../../webrtc-unreliable-client/client" } diff --git a/socket/client/src/backends/miniquad/naia_socket.js b/socket/client/src/backends/miniquad/naia_socket.js index e1dc5eba0..8bea4c664 100644 --- a/socket/client/src/backends/miniquad/naia_socket.js +++ b/socket/client/src/backends/miniquad/naia_socket.js @@ -7,7 +7,7 @@ const naia_socket = { plugin: function (importObject) { importObject.env.naia_is_connected = function () { return naia_socket.is_connected(); }; - importObject.env.naia_connect = function (address, rtc_path) { naia_socket.connect(address, rtc_path); }; + importObject.env.naia_connect = function (address, rtc_path, auth_str) { naia_socket.connect(address, rtc_path, auth_str); }; importObject.env.naia_disconnect = function () { naia_socket.disconnect(); }; importObject.env.naia_send = function (message) { return naia_socket.send(message); }; importObject.env.naia_create_string = function (buf, max_len) { return naia_socket.js_create_string(buf, max_len); }; @@ -29,7 +29,7 @@ const naia_socket = { } }, - connect: function (server_socket_address, rtc_path) { + connect: function (server_socket_address, rtc_path, auth_str) { let server_socket_address_string = naia_socket.get_js_object(server_socket_address); let rtc_path_string = naia_socket.get_js_object(rtc_path); let SESSION_ADDRESS = server_socket_address_string + rtc_path_string; @@ -71,6 +71,9 @@ const naia_socket = { }).then(function() { let request = new XMLHttpRequest(); request.open("POST", SESSION_ADDRESS); + if (auth_str.length > 0) { + request.setRequestHeader("Authorization", auth_str); + } request.onload = function() { if (request.status === 200) { let response = JSON.parse(request.responseText); diff --git a/socket/client/src/backends/miniquad/shared.rs b/socket/client/src/backends/miniquad/shared.rs index bdcb998b2..4f745694f 100644 --- a/socket/client/src/backends/miniquad/shared.rs +++ b/socket/client/src/backends/miniquad/shared.rs @@ -19,7 +19,7 @@ pub static mut SERVER_ADDR: ServerAddr = ServerAddr::Finding; // Javascript methods extern "C" { pub fn naia_is_connected() -> bool; - pub fn naia_connect(server_socket_address: JsObject, rtc_path: JsObject); + pub fn naia_connect(server_socket_address: JsObject, rtc_path: JsObject, auth_str: JsObject); pub fn naia_disconnect(); pub fn naia_send(message: JsObject) -> bool; pub fn naia_free_object(js_object: JsObjectWeak); diff --git a/socket/client/src/backends/miniquad/socket.rs b/socket/client/src/backends/miniquad/socket.rs index c2738c7b7..f756592ef 100644 --- a/socket/client/src/backends/miniquad/socket.rs +++ b/socket/client/src/backends/miniquad/socket.rs @@ -22,15 +22,41 @@ impl Socket { pub fn connect( server_session_url: &str, config: &SocketConfig, + ) -> (Box, Box) { + Self::connect_inner(server_session_url, config, None) + } + /// Connects to the given server address + pub fn connect_with_auth( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + ) -> (Box, Box) { + Self::connect_inner(server_session_url, config, Some(auth_bytes)) + } + /// Connects to the given server address + fn connect_inner( + server_session_url: &str, + config: &SocketConfig, + auth_bytes_opt: Option>, ) -> (Box, Box) { let server_url = parse_server_url(server_session_url); + let auth_str: String = match auth_bytes_opt { + Some(auth_bytes) => { + base64::encode(auth_bytes) + }, + None => { + "".to_string() + } + }; + unsafe { MESSAGE_QUEUE = Some(VecDeque::new()); ERROR_QUEUE = Some(VecDeque::new()); naia_connect( JsObject::string(server_url.to_string().as_str()), JsObject::string(config.rtc_endpoint_path.as_str()), + JsObject::string(auth_str.as_str()), ); } @@ -59,6 +85,14 @@ impl SocketTrait for Socket { server_session_url: &str, config: &SocketConfig, ) -> (Box, Box) { - return Socket::connect(server_session_url, config); + return Self::connect(server_session_url, config); + } + /// Connects to the given server address with authentication + fn connect_with_auth( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + ) -> (Box, Box) { + return Self::connect_with_auth(server_session_url, config, auth_bytes); } } diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 06d415c2c..79f8375e8 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -20,6 +20,22 @@ impl Socket { pub fn connect( server_session_url: &str, config: &SocketConfig, + ) -> (Box, Box) { + return Self::connect_inner(server_session_url, config, None); + } + /// Connects to the given server address with authentication + pub fn connect_with_auth( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + ) -> (Box, Box) { + return Self::connect_inner(server_session_url, config, Some(auth_bytes)); + } + /// Connects to the given server address + fn connect_inner( + server_session_url: &str, + config: &SocketConfig, + auth_bytes_opt: Option>, ) -> (Box, Box) { let server_session_string = format!( "{}{}", @@ -29,7 +45,7 @@ impl Socket { let conditioner_config = config.link_condition.clone(); let (socket, io) = RTCSocket::new(); - get_runtime().spawn(async move { socket.connect(&server_session_string).await }); + get_runtime().spawn(async move { socket.connect(&server_session_string, auth_bytes_opt).await }); // Setup Packet Sender let packet_sender_impl = PacketSenderImpl::new( @@ -60,6 +76,14 @@ impl SocketTrait for Socket { server_session_url: &str, config: &SocketConfig, ) -> (Box, Box) { - return Socket::connect(server_session_url, config); + return Self::connect(server_session_url, config); + } + /// Connects to the given server address with authentication + fn connect_with_auth( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + ) -> (Box, Box) { + return Self::connect_with_auth(server_session_url, config, auth_bytes); } } diff --git a/socket/client/src/backends/socket.rs b/socket/client/src/backends/socket.rs index 9951f4391..911fdb3f3 100644 --- a/socket/client/src/backends/socket.rs +++ b/socket/client/src/backends/socket.rs @@ -9,4 +9,9 @@ pub trait SocketTrait { server_session_url: &str, config: &SocketConfig, ) -> (Box, Box); + fn connect_with_auth( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + ) -> (Box, Box); } diff --git a/socket/client/src/backends/wasm_bindgen/data_channel.rs b/socket/client/src/backends/wasm_bindgen/data_channel.rs index 765c20f56..13ec61632 100644 --- a/socket/client/src/backends/wasm_bindgen/data_channel.rs +++ b/socket/client/src/backends/wasm_bindgen/data_channel.rs @@ -24,17 +24,23 @@ pub struct FindAddrFuncInner(pub Box); // PeerConnection pub struct DataChannel { server_session_url: String, + auth_bytes_opt: Option>, message_channel: MessageChannel, addr_cell: AddrCell, find_addr_func: Rc>, } impl DataChannel { - pub fn new(config: &SocketConfig, server_session_url: &str) -> Self { + pub fn new( + config: &SocketConfig, + server_session_url: &str, + auth_bytes_opt: Option>, + ) -> Self { let server_url = parse_server_url(server_session_url); Self { server_session_url: format!("{}{}", server_url, config.rtc_endpoint_path.clone()), + auth_bytes_opt, message_channel: MessageChannel::new().expect("can't create message channel"), addr_cell: AddrCell::new(), find_addr_func: Rc::new(RefCell::new(FindAddrFuncInner(Box::new(move |_| {})))), @@ -99,12 +105,14 @@ impl DataChannel { let addr_cell_2 = self.addr_cell.clone(); let addr_func_2 = self.find_addr_func.clone(); let server_url_msg = self.server_session_url.clone(); + let auth_bytes_opt_2 = self.auth_bytes_opt.clone(); let peer_offer_func: Box = Box::new(move |e: JsValue| { let session_description = e.into(); let peer_3 = peer_2.clone(); let addr_cell_3 = addr_cell_2.clone(); let addr_func_3 = addr_func_2.clone(); let server_url_msg_2 = server_url_msg.clone(); + let auth_bytes_opt_3 = auth_bytes_opt_2.clone(); let peer_desc_func: Box = Box::new(move |_: JsValue| { let request = XmlHttpRequest::new().expect("can't create new XmlHttpRequest"); @@ -114,6 +122,11 @@ impl DataChannel { .unwrap_or_else(|err| { info!("can't POST to server session url. {:?}", err) }); + if let Some(auth_bytes) = &auth_bytes_opt_3 { + let base64_encoded = base64::encode(auth_bytes); + request.set_request_header("Authorization", &base64_encoded) + .expect("Failed to set request header"); + } let request_2 = request.clone(); let peer_4 = peer_3.clone(); diff --git a/socket/client/src/backends/wasm_bindgen/socket.rs b/socket/client/src/backends/wasm_bindgen/socket.rs index 53d806fac..21d85cc15 100644 --- a/socket/client/src/backends/wasm_bindgen/socket.rs +++ b/socket/client/src/backends/wasm_bindgen/socket.rs @@ -15,12 +15,32 @@ use super::{ pub struct Socket; impl Socket { + /// Connects to the given server address pub fn connect( server_session_url: &str, config: &SocketConfig, + ) -> (Box, Box) + { + return Self::connect_inner(server_session_url, config, None); + } + /// Connects to the given server address with authentication + pub fn connect_with_auth( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + ) -> (Box, Box) + { + return Self::connect_inner(server_session_url, config, Some(auth_bytes)); + } + + /// Connects to the given server address + fn connect_inner( + server_session_url: &str, + config: &SocketConfig, + auth_bytes_opt: Option>, ) -> (Box, Box) { - let data_channel = DataChannel::new(config, server_session_url); + let data_channel = DataChannel::new(config, server_session_url, auth_bytes_opt); let data_port = data_channel.data_port(); let addr_cell = data_channel.addr_cell(); @@ -72,7 +92,17 @@ impl SocketTrait for Socket { fn connect( server_session_url: &str, config: &SocketConfig, - ) -> (Box, Box) { - return Socket::connect(server_session_url, config); + ) -> (Box, Box) + { + return Self::connect(server_session_url, config); + } + /// Connects to the given server address with authentication + fn connect_with_auth( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + ) -> (Box, Box) + { + return Self::connect_with_auth(server_session_url, config, auth_bytes); } } From 186788e85bc3c63914b0b9a04d93dad273ba38c9 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 20 Apr 2024 20:38:23 -0500 Subject: [PATCH 51/99] update run configurations --- ...ket_Demo_Client__mquad___Wasm___BUILD_.xml | 19 +++++++++++++++++++ ...et_Demo_Client__mquad___Wasm___DEPLOY_.xml | 6 +++--- ..._Demo_Client__wbindgen___Wasm___BUILD_.xml | 19 +++++++++++++++++++ 3 files changed, 41 insertions(+), 3 deletions(-) create mode 100644 .idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___BUILD_.xml create mode 100644 .idea/runConfigurations/Socket_Demo_Client__wbindgen___Wasm___BUILD_.xml diff --git a/.idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___BUILD_.xml b/.idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___BUILD_.xml new file mode 100644 index 000000000..6abfab8ec --- /dev/null +++ b/.idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___BUILD_.xml @@ -0,0 +1,19 @@ + + + + \ No newline at end of file diff --git a/.idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___DEPLOY_.xml b/.idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___DEPLOY_.xml index 25129379b..4b6e9f2a3 100644 --- a/.idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___DEPLOY_.xml +++ b/.idea/runConfigurations/Socket_Demo_Client__mquad___Wasm___DEPLOY_.xml @@ -2,14 +2,14 @@

: Send + Sync { fn receive_messages( &mut self, message_kinds: &MessageKinds, + now: &Instant, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec

; diff --git a/shared/src/messages/channels/receivers/reliable_message_receiver.rs b/shared/src/messages/channels/receivers/reliable_message_receiver.rs index fe57c3c6e..636ebf687 100644 --- a/shared/src/messages/channels/receivers/reliable_message_receiver.rs +++ b/shared/src/messages/channels/receivers/reliable_message_receiver.rs @@ -1,4 +1,5 @@ use naia_serde::{BitReader, SerdeErr}; +use naia_socket_shared::Instant; use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::{ @@ -155,10 +156,11 @@ impl ChannelReceiver for ReliableMessageR fn receive_messages( &mut self, message_kinds: &MessageKinds, + now: &Instant, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec { - if let Some(list) = entity_waitlist.collect_ready_items(&mut self.waitlist_store) { + if let Some(list) = entity_waitlist.collect_ready_items(now, &mut self.waitlist_store) { for (first_index, mut full_message) in list { full_message.relations_complete(converter); let incoming_messages = self.arranger.process(first_index, full_message); diff --git a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs index ae3298225..74edbf972 100644 --- a/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/sequenced_unreliable_receiver.rs @@ -1,6 +1,7 @@ use std::mem; use naia_serde::{BitReader, SerdeErr}; +use naia_socket_shared::Instant; use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::{ @@ -67,10 +68,11 @@ impl ChannelReceiver for SequencedUnreliableReceiver { fn receive_messages( &mut self, _message_kinds: &MessageKinds, + now: &Instant, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec { - if let Some(list) = entity_waitlist.collect_ready_items(&mut self.waitlist_store) { + if let Some(list) = entity_waitlist.collect_ready_items(now, &mut self.waitlist_store) { for (message_index, mut message) in list { message.relations_complete(converter); self.arrange_message(message_index, message); diff --git a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs index fa1d6c85c..c8dc5c41d 100644 --- a/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs +++ b/shared/src/messages/channels/receivers/unordered_unreliable_receiver.rs @@ -1,6 +1,7 @@ use std::{collections::VecDeque, mem}; use naia_serde::{BitReader, Serde, SerdeErr}; +use naia_socket_shared::Instant; use crate::messages::channels::senders::request_sender::LocalRequestId; use crate::{ @@ -49,10 +50,11 @@ impl ChannelReceiver for UnorderedUnreliableReceiver { fn receive_messages( &mut self, _message_kinds: &MessageKinds, + now: &Instant, entity_waitlist: &mut EntityWaitlist, converter: &dyn LocalEntityAndGlobalEntityConverter, ) -> Vec { - if let Some(list) = entity_waitlist.collect_ready_items(&mut self.waitlist_store) { + if let Some(list) = entity_waitlist.collect_ready_items(now, &mut self.waitlist_store) { for mut message in list { message.relations_complete(converter); self.incoming_messages.push_back(message); diff --git a/shared/src/messages/channels/senders/reliable_sender.rs b/shared/src/messages/channels/senders/reliable_sender.rs index 0dea52536..52e5ee422 100644 --- a/shared/src/messages/channels/senders/reliable_sender.rs +++ b/shared/src/messages/channels/senders/reliable_sender.rs @@ -90,7 +90,7 @@ impl ChannelSender

for ReliableSender

{ for (message_index, last_sent_opt, message) in self.sending_messages.iter_mut().flatten() { let mut should_send = false; if let Some(last_sent) = last_sent_opt { - if last_sent.elapsed() >= resend_duration { + if last_sent.elapsed(now) >= resend_duration { should_send = true; } } else { diff --git a/shared/src/messages/message_manager.rs b/shared/src/messages/message_manager.rs index 8fa79d732..8e455fea9 100644 --- a/shared/src/messages/message_manager.rs +++ b/shared/src/messages/message_manager.rs @@ -324,6 +324,7 @@ impl MessageManager { pub fn receive_messages( &mut self, message_kinds: &MessageKinds, + now: &Instant, global_entity_converter: &dyn EntityAndGlobalEntityConverter, local_entity_converter: &dyn EntityAndLocalEntityConverter, entity_waitlist: &mut EntityWaitlist, @@ -334,7 +335,7 @@ impl MessageManager { // TODO: shouldn't we have a priority mechanisms between channels? for (channel_kind, channel) in &mut self.channel_receivers { let messages = - channel.receive_messages(message_kinds, entity_waitlist, &entity_converter); + channel.receive_messages(message_kinds, now, entity_waitlist, &entity_converter); output.push((channel_kind.clone(), messages)); } output diff --git a/shared/src/world/host/host_world_manager.rs b/shared/src/world/host/host_world_manager.rs index ca0ec1d32..c655989cd 100644 --- a/shared/src/world/host/host_world_manager.rs +++ b/shared/src/world/host/host_world_manager.rs @@ -155,19 +155,19 @@ impl HostWorldManager { // Messages - pub fn handle_dropped_packets(&mut self, rtt_millis: &f32) { - self.handle_dropped_update_packets(rtt_millis); - self.handle_dropped_action_packets(); + pub fn handle_dropped_packets(&mut self, now: &Instant, rtt_millis: &f32) { + self.handle_dropped_update_packets(now, rtt_millis); + self.handle_dropped_action_packets(now); } // Collecting - fn handle_dropped_action_packets(&mut self) { + fn handle_dropped_action_packets(&mut self, now: &Instant) { let mut pop = false; loop { if let Some((_, (time_sent, _))) = self.sent_action_packets.front() { - if time_sent.elapsed() > ACTION_RECORD_TTL { + if time_sent.elapsed(now) > ACTION_RECORD_TTL { pop = true; } } else { @@ -181,13 +181,13 @@ impl HostWorldManager { } } - fn handle_dropped_update_packets(&mut self, rtt_millis: &f32) { + fn handle_dropped_update_packets(&mut self, now: &Instant, rtt_millis: &f32) { let drop_duration = Duration::from_millis((DROP_UPDATE_RTT_FACTOR * rtt_millis) as u64); { let mut dropped_packets = Vec::new(); for (packet_index, (time_sent, _)) in &self.sent_updates { - if time_sent.elapsed() > drop_duration { + if time_sent.elapsed(now) > drop_duration { dropped_packets.push(*packet_index); } } diff --git a/shared/src/world/local_world_manager.rs b/shared/src/world/local_world_manager.rs index 323276c38..9f5ba85ba 100644 --- a/shared/src/world/local_world_manager.rs +++ b/shared/src/world/local_world_manager.rs @@ -51,11 +51,14 @@ impl LocalWorldManager { } fn process_reserved_entity_timeouts(&mut self) { + + let now = Instant::now(); + loop { let Some((timeout, _)) = self.reserved_entities_ttls.front() else { break; }; - if timeout.elapsed() < self.reserved_entity_ttl { + if timeout.elapsed(&now) < self.reserved_entity_ttl { break; } let (_, world_entity) = self.reserved_entities_ttls.pop_front().unwrap(); diff --git a/shared/src/world/remote/entity_waitlist.rs b/shared/src/world/remote/entity_waitlist.rs index 9e69da925..efcc27bfc 100644 --- a/shared/src/world/remote/entity_waitlist.rs +++ b/shared/src/world/remote/entity_waitlist.rs @@ -74,9 +74,10 @@ impl EntityWaitlist { pub fn collect_ready_items( &mut self, + now: &Instant, waitlist_store: &mut WaitlistStore, ) -> Option> { - self.check_handle_ttls(); + self.check_handle_ttls(now); waitlist_store.remove_expired_items(&mut self.removed_handles); if self.ready_handles.is_empty() { @@ -146,12 +147,12 @@ impl EntityWaitlist { } } - fn check_handle_ttls(&mut self) { + fn check_handle_ttls(&mut self, now: &Instant) { loop { let Some((ttl, _)) = self.handle_ttls.front() else { break; }; - if ttl.elapsed() < self.handle_ttl { + if ttl.elapsed(now) < self.handle_ttl { break; } let (_, handle) = self.handle_ttls.pop_front().unwrap(); diff --git a/shared/src/world/remote/remote_world_manager.rs b/shared/src/world/remote/remote_world_manager.rs index 5a03083b6..eec9239f2 100644 --- a/shared/src/world/remote/remote_world_manager.rs +++ b/shared/src/world/remote/remote_world_manager.rs @@ -4,6 +4,7 @@ use std::{ }; use log::{info, warn}; +use naia_socket_shared::Instant; use crate::{ world::{ @@ -54,6 +55,7 @@ impl RemoteWorldManager { local_world_manager: &mut LocalWorldManager, component_kinds: &ComponentKinds, world: &mut W, + now: &Instant, world_events: RemoteWorldEvents, ) -> Vec> { self.process_updates( @@ -61,12 +63,14 @@ impl RemoteWorldManager { local_world_manager, component_kinds, world, + now, world_events.incoming_updates, ); self.process_actions( global_world_manager, local_world_manager, world, + now, world_events.incoming_actions, world_events.incoming_components, ); @@ -83,6 +87,7 @@ impl RemoteWorldManager { global_world_manager: &dyn GlobalWorldManagerType, local_world_manager: &mut LocalWorldManager, world: &mut W, + now: &Instant, incoming_actions: Vec>, incoming_components: HashMap<(RemoteEntity, ComponentKind), Box>, ) { @@ -93,7 +98,7 @@ impl RemoteWorldManager { incoming_actions, incoming_components, ); - self.process_waitlist_actions(global_world_manager, local_world_manager, world); + self.process_waitlist_actions(global_world_manager, local_world_manager, world, now); } /// For each [`EntityAction`] that can be executed now, @@ -246,10 +251,11 @@ impl RemoteWorldManager { global_world_manager: &dyn GlobalWorldManagerType, local_world_manager: &mut LocalWorldManager, world: &mut W, + now: &Instant, ) { if let Some(list) = self .entity_waitlist - .collect_ready_items(&mut self.insert_waitlist_store) + .collect_ready_items(now, &mut self.insert_waitlist_store) { let converter = EntityConverter::new( global_world_manager.to_global_entity_converter(), @@ -281,6 +287,7 @@ impl RemoteWorldManager { local_world_manager: &mut LocalWorldManager, component_kinds: &ComponentKinds, world: &mut W, + now: &Instant, incoming_updates: Vec<(Tick, E, ComponentUpdate)>, ) { self.process_ready_updates( @@ -290,7 +297,7 @@ impl RemoteWorldManager { world, incoming_updates, ); - self.process_waitlist_updates(global_world_manager, local_world_manager, world); + self.process_waitlist_updates(global_world_manager, local_world_manager, world, now); } /// Process component updates from raw bits for a given entity @@ -390,6 +397,7 @@ impl RemoteWorldManager { global_world_manager: &dyn GlobalWorldManagerType, local_world_manager: &LocalWorldManager, world: &mut W, + now: &Instant, ) { let converter = EntityConverter::new( global_world_manager.to_global_entity_converter(), @@ -397,7 +405,7 @@ impl RemoteWorldManager { ); if let Some(list) = self .entity_waitlist - .collect_ready_items(&mut self.update_waitlist_store) + .collect_ready_items(now, &mut self.update_waitlist_store) { for (tick, world_entity, component_kind, ready_update) in list { info!("processing waiting update!"); diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 9de3ca982..28756899c 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -2,15 +2,15 @@ use naia_socket_shared::{parse_server_url, SocketConfig}; use webrtc_unreliable_client::Socket as RTCSocket; +use super::{packet_receiver::PacketReceiverImpl, packet_sender::PacketSenderImpl}; use crate::{ - identity_receiver::IdentityReceiver, backends::{native::runtime::get_runtime, socket::SocketTrait}, conditioned_packet_receiver::ConditionedPacketReceiver, + identity_receiver::IdentityReceiver, packet_receiver::PacketReceiver, packet_sender::PacketSender, IdentityReceiverImpl, }; -use super::{packet_receiver::PacketReceiverImpl, packet_sender::PacketSenderImpl}; /// A client-side socket which communicates with an underlying unordered & /// unreliable protocol diff --git a/socket/client/src/backends/wasm_bindgen/socket.rs b/socket/client/src/backends/wasm_bindgen/socket.rs index cd8824376..6929ec34b 100644 --- a/socket/client/src/backends/wasm_bindgen/socket.rs +++ b/socket/client/src/backends/wasm_bindgen/socket.rs @@ -1,13 +1,13 @@ use naia_socket_shared::SocketConfig; -use crate::{ - backends::socket::SocketTrait, conditioned_packet_receiver::ConditionedPacketReceiver, - packet_receiver::PacketReceiver, packet_sender::PacketSender, IdentityReceiver, -}; use super::{ addr_cell::AddrCell, data_channel::DataChannel, data_port::DataPort, packet_receiver::PacketReceiverImpl, packet_sender::PacketSenderImpl, }; +use crate::{ + backends::socket::SocketTrait, conditioned_packet_receiver::ConditionedPacketReceiver, + packet_receiver::PacketReceiver, packet_sender::PacketSender, IdentityReceiver, +}; /// A client-side socket which communicates with an underlying unordered & /// unreliable protocol diff --git a/socket/client/src/conditioned_packet_receiver.rs b/socket/client/src/conditioned_packet_receiver.rs index ac58b3a72..e2979992f 100644 --- a/socket/client/src/conditioned_packet_receiver.rs +++ b/socket/client/src/conditioned_packet_receiver.rs @@ -1,4 +1,4 @@ -use naia_socket_shared::{link_condition_logic, LinkConditionerConfig, TimeQueue}; +use naia_socket_shared::{Instant, link_condition_logic, LinkConditionerConfig, TimeQueue}; use super::{ error::NaiaClientSocketError, packet_receiver::PacketReceiver, server_addr::ServerAddr, @@ -50,8 +50,9 @@ impl PacketReceiver for ConditionedPacketReceiver { } } - if self.time_queue.has_item() { - self.last_payload = Some(self.time_queue.pop_item().unwrap()); + let now = Instant::now(); + if self.time_queue.has_item(&now) { + self.last_payload = Some(self.time_queue.pop_item(&now).unwrap()); return Ok(Some(self.last_payload.as_ref().unwrap())); } else { Ok(None) diff --git a/socket/server/src/conditioned_packet_receiver.rs b/socket/server/src/conditioned_packet_receiver.rs index 2c5f1c755..8f9fff7cd 100644 --- a/socket/server/src/conditioned_packet_receiver.rs +++ b/socket/server/src/conditioned_packet_receiver.rs @@ -2,7 +2,7 @@ use std::net::SocketAddr; use smol::channel::Receiver; -use naia_socket_shared::{link_condition_logic, LinkConditionerConfig, TimeQueue}; +use naia_socket_shared::{Instant, link_condition_logic, LinkConditionerConfig, TimeQueue}; use super::{error::NaiaServerSocketError, packet_receiver::PacketReceiver}; @@ -49,8 +49,9 @@ impl PacketReceiver for ConditionedPacketReceiverImpl { } } - if self.time_queue.has_item() { - let (address, payload) = self.time_queue.pop_item().unwrap(); + let now = Instant::now(); + if self.time_queue.has_item(&now) { + let (address, payload) = self.time_queue.pop_item(&now).unwrap(); self.last_payload = Some(payload); return Ok(Some((address, self.last_payload.as_ref().unwrap()))); } else { diff --git a/socket/shared/src/backends/miniquad/instant.rs b/socket/shared/src/backends/miniquad/instant.rs index 1c8674be1..2cd7f57b9 100644 --- a/socket/shared/src/backends/miniquad/instant.rs +++ b/socket/shared/src/backends/miniquad/instant.rs @@ -17,9 +17,9 @@ impl Instant { } /// Returns time elapsed since the Instant - pub fn elapsed(&self) -> Duration { + pub fn elapsed(&self, now: &Self) -> Duration { unsafe { - let inner_duration = naia_now() - self.inner; + let inner_duration = now.inner - self.inner; let seconds: u64 = (inner_duration as u64) / 1000; let nanos: u32 = ((inner_duration as u32) % 1000) * 1000000; Duration::new(seconds, nanos) @@ -27,15 +27,20 @@ impl Instant { } /// Returns time until the Instant occurs - pub fn until(&self) -> Duration { + pub fn until(&self, now: &Self) -> Duration { unsafe { - let inner_duration = self.inner - naia_now(); + let inner_duration = self.inner - now.inner; let seconds: u64 = (inner_duration as u64) / 1000; let nanos: u32 = ((inner_duration as u32) % 1000) * 1000000; Duration::new(seconds, nanos) } } + /// Returns whether the Instant is after another Instant + pub fn is_after(&self, other: &Self) -> bool { + self.inner > other.inner + } + /// Adds a given number of milliseconds to the Instant pub fn add_millis(&mut self, millis: u32) { let millis_f64: f64 = millis.into(); diff --git a/socket/shared/src/backends/native/instant.rs b/socket/shared/src/backends/native/instant.rs index 020ee7994..97ea55312 100644 --- a/socket/shared/src/backends/native/instant.rs +++ b/socket/shared/src/backends/native/instant.rs @@ -9,19 +9,23 @@ pub struct Instant { impl Instant { /// Creates an Instant from the moment the method is called pub fn now() -> Self { - Instant { + Self { inner: std::time::Instant::now(), } } /// Returns time elapsed since the Instant - pub fn elapsed(&self) -> Duration { - self.inner.elapsed() + pub fn elapsed(&self, now: &Self) -> Duration { + now.inner - self.inner } /// Returns time until the Instant occurs - pub fn until(&self) -> Duration { - self.inner.duration_since(std::time::Instant::now()) + pub fn until(&self, now: &Self) -> Duration { + self.inner.duration_since(now.inner()) + } + + pub fn is_after(&self, other: &Self) -> bool { + self.inner > other.inner } /// Adds a given number of milliseconds to the Instant diff --git a/socket/shared/src/backends/wasm_bindgen/instant.rs b/socket/shared/src/backends/wasm_bindgen/instant.rs index cecc332b4..06a01f76b 100644 --- a/socket/shared/src/backends/wasm_bindgen/instant.rs +++ b/socket/shared/src/backends/wasm_bindgen/instant.rs @@ -14,21 +14,26 @@ impl Instant { } /// Returns time elapsed since the Instant - pub fn elapsed(&self) -> Duration { - let inner_duration = Date::now() - self.inner; + pub fn elapsed(&self, now: &Self) -> Duration { + let inner_duration = now.inner - self.inner; let seconds: u64 = (inner_duration as u64) / 1000; let nanos: u32 = ((inner_duration as u32) % 1000) * 1000000; Duration::new(seconds, nanos) } /// Returns time until the Instant occurs - pub fn until(&self) -> Duration { - let inner_duration = self.inner - Date::now(); + pub fn until(&self, now: &Self) -> Duration { + let inner_duration = self.inner - now.inner; let seconds: u64 = (inner_duration as u64) / 1000; let nanos: u32 = ((inner_duration as u32) % 1000) * 1000000; Duration::new(seconds, nanos) } + /// Returns whether the Instant is after another Instant + pub fn is_after(&self, other: &Self) -> bool { + self.inner > other.inner + } + /// Adds a given number of milliseconds to the Instant pub fn add_millis(&mut self, millis: u32) { let millis_f64: f64 = millis.into(); diff --git a/socket/shared/src/time_queue.rs b/socket/shared/src/time_queue.rs index 8e1f96779..6324c5518 100644 --- a/socket/shared/src/time_queue.rs +++ b/socket/shared/src/time_queue.rs @@ -3,7 +3,7 @@ use std::{cmp::Ordering, collections::BinaryHeap}; use super::Instant; /// A queue for items marked by time, will only ever pop items from the queue if -/// the time +/// the time passes #[derive(Clone)] pub struct TimeQueue { queue: BinaryHeap>, @@ -24,20 +24,24 @@ impl TimeQueue { self.queue.push(ItemContainer { instant, item }); } - /// Returns whether or not there is an item that is ready to be returned - pub fn has_item(&self) -> bool { + /// Returns whether or not there is an item whose time has elapsed on the queue + pub fn has_item(&self, now: &Instant) -> bool { if self.queue.is_empty() { return false; } if let Some(item) = self.queue.peek() { - return item.instant <= Instant::now(); + // item's instant has passed, so it's ready to be returned + + let will_pop = item.instant.is_after(now); + + return will_pop; } false } - /// Pops an item from the queue if the sufficient time has elapsed - pub fn pop_item(&mut self) -> Option { - if self.has_item() { + /// Pops an item from the queue if it's time has elapsed + pub fn pop_item(&mut self, now: &Instant) -> Option { + if self.has_item(now) { if let Some(container) = self.queue.pop() { return Some(container.item); } From 2ebedf42bb409ce6d5d8158768eefa9b0fc850dc Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 27 Apr 2024 21:42:46 -0500 Subject: [PATCH 73/99] - allow client to pass raw bytes through as connection auth data --- adapters/bevy/client/src/client.rs | 2 ++ client/src/client.rs | 31 ++++++++++++++++-------------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 248b16795..2b0931ebd 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -46,6 +46,8 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { self.client.client.auth(auth); } + pub fn auth_bytes(&mut self, bytes: &[u8]) { self.client.client.auth_bytes(bytes); } + pub fn connect>>(&mut self, socket: S) { self.client.client.connect(socket); } diff --git a/client/src/client.rs b/client/src/client.rs index 9bf3f749c..389f46a29 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -31,7 +31,7 @@ pub struct Client { client_config: ClientConfig, protocol: Protocol, // Connection - auth_message: Option, + auth_message: Option>, io: Io, server_connection: Option>, handshake_manager: Box, @@ -84,10 +84,21 @@ impl Client { /// Set the auth object to use when setting up a connection with the Server pub fn auth(&mut self, auth: M) { - self.auth_message = Some(MessageContainer::from_write( - Box::new(auth), + // get auth bytes + let mut bit_writer = BitWriter::new(); + auth.write( + &self.protocol.message_kinds, + &mut bit_writer, &mut FakeEntityConverter, - )); + ); + let auth_bytes = bit_writer.to_bytes(); + self.auth_bytes(&auth_bytes) + } + + /// Set the auth bytes to use when setting up a connection with the Server + /// This is helpful to customize your auth flow + pub fn auth_bytes(&mut self, bytes: &[u8]) { + self.auth_message = Some(bytes.to_vec()); } /// Connect to the given server address @@ -96,20 +107,12 @@ impl Client { panic!("Client has already initiated a connection, cannot initiate a new one. TIP: Check client.is_disconnected() before calling client.connect()"); } - if let Some(auth_message) = &self.auth_message { - // get auth bytes - let mut bit_writer = BitWriter::new(); - auth_message.write( - &self.protocol.message_kinds, - &mut bit_writer, - &mut FakeEntityConverter, - ); - let auth_bytes = bit_writer.to_bytes().to_vec(); + if let Some(auth_bytes) = &self.auth_message { // connect with auth let boxed_socket: Box = socket.into(); let (id_receiver, packet_sender, packet_receiver) = - boxed_socket.connect_with_auth(auth_bytes); + boxed_socket.connect_with_auth(auth_bytes.clone()); self.io.load(id_receiver, packet_sender, packet_receiver); } else { // connect without auth From 5be8db5012e571696e650cc3e1ba9b900087758e Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 28 Apr 2024 17:55:29 -0500 Subject: [PATCH 74/99] - Client.auth_bytes was not a good idea, rolling back --- adapters/bevy/client/src/client.rs | 2 -- client/src/client.rs | 6 ------ 2 files changed, 8 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 2b0931ebd..248b16795 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -46,8 +46,6 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { self.client.client.auth(auth); } - pub fn auth_bytes(&mut self, bytes: &[u8]) { self.client.client.auth_bytes(bytes); } - pub fn connect>>(&mut self, socket: S) { self.client.client.connect(socket); } diff --git a/client/src/client.rs b/client/src/client.rs index 389f46a29..0978456e4 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -95,12 +95,6 @@ impl Client { self.auth_bytes(&auth_bytes) } - /// Set the auth bytes to use when setting up a connection with the Server - /// This is helpful to customize your auth flow - pub fn auth_bytes(&mut self, bytes: &[u8]) { - self.auth_message = Some(bytes.to_vec()); - } - /// Connect to the given server address pub fn connect>>(&mut self, socket: S) { if !self.is_disconnected() { From 447b6e73a610afe39e5768403c2fe148da3c1a1e Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 28 Apr 2024 18:05:40 -0500 Subject: [PATCH 75/99] - Client.auth_bytes was not a good idea, rolling back 2 --- client/src/client.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/src/client.rs b/client/src/client.rs index 0978456e4..8e76f71cb 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -92,7 +92,7 @@ impl Client { &mut FakeEntityConverter, ); let auth_bytes = bit_writer.to_bytes(); - self.auth_bytes(&auth_bytes) + self.auth_message = Some(auth_bytes.to_vec()); } /// Connect to the given server address From 564328651092240b5fba8bae35cd8faa83b5c57a Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Wed, 1 May 2024 23:27:14 -0500 Subject: [PATCH 76/99] new functionality to have more control over webrtc signaling http request, able to add artificial headers that may be useful for dealing with api gateways and such --- adapters/bevy/client/src/client.rs | 4 ++ adapters/bevy/shared/src/protocol.rs | 4 ++ client/src/client.rs | 41 ++++++++++++++----- client/src/transport/mod.rs | 17 ++++++++ client/src/transport/webrtc.rs | 33 +++++++++++++++ socket/client/src/backends/miniquad/socket.rs | 32 ++++++++++++++- socket/client/src/backends/native/socket.rs | 36 ++++++++++++++-- .../src/backends/wasm_bindgen/data_channel.rs | 12 ++++++ .../src/backends/wasm_bindgen/socket.rs | 35 ++++++++++++++-- socket/shared/src/time_queue.rs | 2 +- 10 files changed, 197 insertions(+), 19 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 248b16795..0b4ab7a4f 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -46,6 +46,10 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { self.client.client.auth(auth); } + pub fn auth_headers(&mut self, headers: Vec<(String, String)>) { + self.client.client.auth_headers(headers); + } + pub fn connect>>(&mut self, socket: S) { self.client.client.connect(socket); } diff --git a/adapters/bevy/shared/src/protocol.rs b/adapters/bevy/shared/src/protocol.rs index 71ace73dc..5c83979bc 100644 --- a/adapters/bevy/shared/src/protocol.rs +++ b/adapters/bevy/shared/src/protocol.rs @@ -102,6 +102,10 @@ impl Protocol { self.inner } + pub fn inner(&self) -> &InnerProtocol { + &self.inner + } + fn check_lock(&self) { self.inner.check_lock(); } diff --git a/client/src/client.rs b/client/src/client.rs index 8e76f71cb..cecf30c09 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -32,6 +32,7 @@ pub struct Client { protocol: Protocol, // Connection auth_message: Option>, + auth_headers: Option>, io: Io, server_connection: Option>, handshake_manager: Box, @@ -65,6 +66,7 @@ impl Client { protocol, // Connection auth_message: None, + auth_headers: None, io: Io::new( &client_config.connection.bandwidth_measure_duration, &compression_config, @@ -95,6 +97,10 @@ impl Client { self.auth_message = Some(auth_bytes.to_vec()); } + pub fn auth_headers(&mut self, headers: Vec<(String, String)>) { + self.auth_headers = Some(headers); + } + /// Connect to the given server address pub fn connect>>(&mut self, socket: S) { if !self.is_disconnected() { @@ -102,17 +108,32 @@ impl Client { } if let Some(auth_bytes) = &self.auth_message { - - // connect with auth - let boxed_socket: Box = socket.into(); - let (id_receiver, packet_sender, packet_receiver) = - boxed_socket.connect_with_auth(auth_bytes.clone()); - self.io.load(id_receiver, packet_sender, packet_receiver); + if let Some(auth_headers) = &self.auth_headers { + // connect with auth & headers + let boxed_socket: Box = socket.into(); + let (id_receiver, packet_sender, packet_receiver) = + boxed_socket.connect_with_auth_and_headers(auth_bytes.clone(), auth_headers.clone()); + self.io.load(id_receiver, packet_sender, packet_receiver); + } else { + // connect with auth + let boxed_socket: Box = socket.into(); + let (id_receiver, packet_sender, packet_receiver) = + boxed_socket.connect_with_auth(auth_bytes.clone()); + self.io.load(id_receiver, packet_sender, packet_receiver); + } } else { - // connect without auth - let boxed_socket: Box = socket.into(); - let (id_receiver, packet_sender, packet_receiver) = boxed_socket.connect(); - self.io.load(id_receiver, packet_sender, packet_receiver); + if let Some(auth_headers) = &self.auth_headers { + // connect with auth headers + let boxed_socket: Box = socket.into(); + let (id_receiver, packet_sender, packet_receiver) = + boxed_socket.connect_with_auth_headers(auth_headers.clone()); + self.io.load(id_receiver, packet_sender, packet_receiver); + } else { + // connect without auth + let boxed_socket: Box = socket.into(); + let (id_receiver, packet_sender, packet_receiver) = boxed_socket.connect(); + self.io.load(id_receiver, packet_sender, packet_receiver); + } } } diff --git a/client/src/transport/mod.rs b/client/src/transport/mod.rs index c5d521451..67592d55a 100644 --- a/client/src/transport/mod.rs +++ b/client/src/transport/mod.rs @@ -41,6 +41,23 @@ mod inner { Box, Box, ); + fn connect_with_auth_headers( + self: Box, + auth_headers: Vec<(String, String)>, + ) -> ( + Box, + Box, + Box, + ); + fn connect_with_auth_and_headers( + self: Box, + auth_bytes: Vec, + auth_headers: Vec<(String, String)>, + ) -> ( + Box, + Box, + Box, + ); } pub trait PacketSender: Send + Sync { diff --git a/client/src/transport/webrtc.rs b/client/src/transport/webrtc.rs index 0a1303809..6324ecc5c 100644 --- a/client/src/transport/webrtc.rs +++ b/client/src/transport/webrtc.rs @@ -97,4 +97,37 @@ impl TransportSocket for Socket { Box::new(inner_receiver), ); } + fn connect_with_auth_headers( + self: Box, + auth_headers: Vec<(String, String)>, + ) -> ( + Box, + Box, + Box, + ) { + let (id_receiver, inner_sender, inner_receiver) = + ClientSocket::connect_with_auth_headers(&self.server_session_url, &self.config, auth_headers); + return ( + Box::new(id_receiver), + Box::new(inner_sender), + Box::new(inner_receiver), + ); + } + fn connect_with_auth_and_headers( + self: Box, + auth_bytes: Vec, + auth_headers: Vec<(String, String)>, + ) -> ( + Box, + Box, + Box, + ) { + let (id_receiver, inner_sender, inner_receiver) = + ClientSocket::connect_with_auth_and_headers(&self.server_session_url, &self.config, auth_bytes, auth_headers); + return ( + Box::new(id_receiver), + Box::new(inner_sender), + Box::new(inner_receiver), + ); + } } diff --git a/socket/client/src/backends/miniquad/socket.rs b/socket/client/src/backends/miniquad/socket.rs index 8aedc259c..0f1b49cbc 100644 --- a/socket/client/src/backends/miniquad/socket.rs +++ b/socket/client/src/backends/miniquad/socket.rs @@ -28,7 +28,7 @@ impl Socket { Box, Box, ) { - return Self::connect_inner(server_session_url, config, None); + return Self::connect_inner(server_session_url, config, None, None); } /// Connects to the given server address with authentication @@ -41,7 +41,34 @@ impl Socket { Box, Box, ) { - return Self::connect_inner(server_session_url, config, Some(auth_bytes)); + return Self::connect_inner(server_session_url, config, Some(auth_bytes), None); + } + + /// Connects to the given server address with authentication + pub fn connect_with_auth_headers( + server_session_url: &str, + config: &SocketConfig, + auth_headers: Vec<(String, String)> + ) -> ( + Box, + Box, + Box, + ) { + return Self::connect_inner(server_session_url, config, None, Some(auth_headers)); + } + + /// Connects to the given server address with authentication + pub fn connect_with_auth_and_headers( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + auth_headers: Vec<(String, String)> + ) -> ( + Box, + Box, + Box, + ) { + return Self::connect_inner(server_session_url, config, Some(auth_bytes), Some(auth_headers)); } /// Connects to the given server address @@ -49,6 +76,7 @@ impl Socket { server_session_url: &str, config: &SocketConfig, auth_bytes_opt: Option>, + auth_headers_opt: Option> ) -> ( Box, Box, diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 28756899c..f03d7dccb 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -26,8 +26,9 @@ impl Socket { Box, Box, ) { - return Self::connect_inner(server_session_url, config, None); + return Self::connect_inner(server_session_url, config, None, None); } + /// Connects to the given server address with authentication pub fn connect_with_auth( server_session_url: &str, @@ -38,13 +39,42 @@ impl Socket { Box, Box, ) { - return Self::connect_inner(server_session_url, config, Some(auth_bytes)); + return Self::connect_inner(server_session_url, config, Some(auth_bytes), None); + } + + /// Connects to the given server address with authentication + pub fn connect_with_auth_headers( + server_session_url: &str, + config: &SocketConfig, + auth_headers: Vec<(String, String)> + ) -> ( + Box, + Box, + Box, + ) { + return Self::connect_inner(server_session_url, config, None, Some(auth_headers)); } + + /// Connects to the given server address with authentication + pub fn connect_with_auth_and_headers( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + auth_headers: Vec<(String, String)> + ) -> ( + Box, + Box, + Box, + ) { + return Self::connect_inner(server_session_url, config, Some(auth_bytes), Some(auth_headers)); + } + /// Connects to the given server address fn connect_inner( server_session_url: &str, config: &SocketConfig, auth_bytes_opt: Option>, + auth_headers_opt: Option>, ) -> ( Box, Box, @@ -59,7 +89,7 @@ impl Socket { let (socket, io) = RTCSocket::new(); get_runtime() - .spawn(async move { socket.connect(&server_session_string, auth_bytes_opt).await }); + .spawn(async move { socket.connect(&server_session_string, auth_bytes_opt, auth_headers_opt).await }); // Setup Packet Sender let packet_sender_impl = PacketSenderImpl::new( diff --git a/socket/client/src/backends/wasm_bindgen/data_channel.rs b/socket/client/src/backends/wasm_bindgen/data_channel.rs index 6ccb793b3..de7948726 100644 --- a/socket/client/src/backends/wasm_bindgen/data_channel.rs +++ b/socket/client/src/backends/wasm_bindgen/data_channel.rs @@ -24,6 +24,7 @@ pub struct FindAddrFuncInner(pub Box); pub struct DataChannel { server_session_url: String, auth_bytes_opt: Option>, + auth_headers_opt: Option>, message_channel: MessageChannel, addr_cell: AddrCell, id_cell: IdentityReceiverImpl, @@ -35,12 +36,14 @@ impl DataChannel { config: &SocketConfig, server_session_url: &str, auth_bytes_opt: Option>, + auth_headers_opt: Option>, ) -> Self { let server_url = parse_server_url(server_session_url); Self { server_session_url: format!("{}{}", server_url, config.rtc_endpoint_path.clone()), auth_bytes_opt, + auth_headers_opt, message_channel: MessageChannel::new().expect("can't create message channel"), addr_cell: AddrCell::new(), id_cell: IdentityReceiverImpl::new(), @@ -112,6 +115,7 @@ impl DataChannel { let id_sender_2 = self.id_cell.clone(); let server_url_msg = self.server_session_url.clone(); let auth_bytes_opt_2 = self.auth_bytes_opt.clone(); + let auth_headers_opt_2 = self.auth_headers_opt.clone(); let peer_offer_func: Box = Box::new(move |e: JsValue| { let session_description = e.into(); let peer_3 = peer_2.clone(); @@ -120,6 +124,7 @@ impl DataChannel { let id_sender_3 = id_sender_2.clone(); let server_url_msg_2 = server_url_msg.clone(); let auth_bytes_opt_3 = auth_bytes_opt_2.clone(); + let auth_headers_opt_3 = auth_headers_opt_2.clone(); let peer_desc_func: Box = Box::new(move |_: JsValue| { let request = XmlHttpRequest::new().expect("can't create new XmlHttpRequest"); @@ -135,6 +140,13 @@ impl DataChannel { .set_request_header("Authorization", &base64_encoded) .expect("Failed to set request header"); } + if let Some(auth_headers) = &auth_headers_opt_3 { + for (key, value) in auth_headers { + request + .set_request_header(key, value) + .expect("Failed to set request header"); + } + } let request_2 = request.clone(); let peer_4 = peer_3.clone(); diff --git a/socket/client/src/backends/wasm_bindgen/socket.rs b/socket/client/src/backends/wasm_bindgen/socket.rs index 6929ec34b..dc9abc542 100644 --- a/socket/client/src/backends/wasm_bindgen/socket.rs +++ b/socket/client/src/backends/wasm_bindgen/socket.rs @@ -23,7 +23,7 @@ impl Socket { Box, Box, ) { - return Self::connect_inner(server_session_url, config, None); + return Self::connect_inner(server_session_url, config, None, None); } /// Connects to the given server address with authentication @@ -36,7 +36,35 @@ impl Socket { Box, Box, ) { - return Self::connect_inner(server_session_url, config, Some(auth_bytes)); + return Self::connect_inner(server_session_url, config, Some(auth_bytes), None); + } + + /// Connects to the given server address with authentication + pub fn connect_with_auth_headers( + server_session_url: &str, + config: &SocketConfig, + auth_headers: Vec<(String, String)> + ) -> ( + Box, + Box, + Box, + ) { + return Self::connect_inner(server_session_url, config, None, Some(auth_headers)); + } + + + /// Connects to the given server address with authentication + pub fn connect_with_auth_and_headers( + server_session_url: &str, + config: &SocketConfig, + auth_bytes: Vec, + auth_headers: Vec<(String, String)> + ) -> ( + Box, + Box, + Box, + ) { + return Self::connect_inner(server_session_url, config, Some(auth_bytes), Some(auth_headers)); } /// Connects to the given server address @@ -44,12 +72,13 @@ impl Socket { server_session_url: &str, config: &SocketConfig, auth_bytes_opt: Option>, + auth_headers_opt: Option>, ) -> ( Box, Box, Box, ) { - let data_channel = DataChannel::new(config, server_session_url, auth_bytes_opt); + let data_channel = DataChannel::new(config, server_session_url, auth_bytes_opt, auth_headers_opt); let data_port = data_channel.data_port(); let addr_cell = data_channel.addr_cell(); diff --git a/socket/shared/src/time_queue.rs b/socket/shared/src/time_queue.rs index 6324c5518..2c052235d 100644 --- a/socket/shared/src/time_queue.rs +++ b/socket/shared/src/time_queue.rs @@ -32,7 +32,7 @@ impl TimeQueue { if let Some(item) = self.queue.peek() { // item's instant has passed, so it's ready to be returned - let will_pop = item.instant.is_after(now); + let will_pop = now.is_after(&item.instant); return will_pop; } From 7a0dcf37ec3ebf2aa30080bfc7188d0a0bb42eae Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 2 May 2024 15:32:23 -0500 Subject: [PATCH 77/99] - protocol object now has a "get_rtc_endpoint" function to get at the rtc_endpoint set for the protocol --- adapters/bevy/shared/src/protocol.rs | 4 ++++ shared/src/protocol.rs | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/adapters/bevy/shared/src/protocol.rs b/adapters/bevy/shared/src/protocol.rs index 5c83979bc..7550b49b0 100644 --- a/adapters/bevy/shared/src/protocol.rs +++ b/adapters/bevy/shared/src/protocol.rs @@ -51,6 +51,10 @@ impl Protocol { self } + pub fn get_rtc_endpoint(&self) -> String { + self.inner.get_rtc_endpoint() + } + pub fn tick_interval(&mut self, duration: Duration) -> &mut Self { self.inner.tick_interval(duration); self diff --git a/shared/src/protocol.rs b/shared/src/protocol.rs index 15e661e25..03b607e88 100644 --- a/shared/src/protocol.rs +++ b/shared/src/protocol.rs @@ -89,6 +89,10 @@ impl Protocol { self } + pub fn get_rtc_endpoint(&self) -> String { + self.socket.rtc_endpoint_path.clone() + } + pub fn tick_interval(&mut self, duration: Duration) -> &mut Self { self.check_lock(); self.tick_interval = duration; From bab581722e77cf233694a6ff72cafbaafdc9ac2c Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 2 May 2024 21:01:27 -0500 Subject: [PATCH 78/99] some additional logging --- shared/src/world/entity/entity_converters.rs | 10 ++++++---- shared/src/world/host/world_channel.rs | 3 ++- socket/server/src/session.rs | 11 +++++++++++ 3 files changed, 19 insertions(+), 5 deletions(-) diff --git a/shared/src/world/entity/entity_converters.rs b/shared/src/world/entity/entity_converters.rs index 41178d11c..49b2edfd2 100644 --- a/shared/src/world/entity/entity_converters.rs +++ b/shared/src/world/entity/entity_converters.rs @@ -336,10 +336,12 @@ impl<'a, 'b, E: Copy + Eq + Hash> LocalEntityAndGlobalEntityConverterMut if result.is_ok() { return result; } - warn!("get_or_reserve_entity(): entity is not owned by user, attempting to reserve"); - return Ok(self + + let host_entity = self .local_world_manager - .host_reserve_entity(&entity) - .copy_to_owned()); + .host_reserve_entity(&entity); + + warn!("get_or_reserve_entity(): entity is not owned by user, attempting to reserve. HostEntity: {:?}", host_entity); + return Ok(host_entity.copy_to_owned()); } } diff --git a/shared/src/world/host/world_channel.rs b/shared/src/world/host/world_channel.rs index a661ae179..052eabe24 100644 --- a/shared/src/world/host/world_channel.rs +++ b/shared/src/world/host/world_channel.rs @@ -4,7 +4,7 @@ use std::{ net::SocketAddr, }; -use log::warn; +use log::{info, warn}; use super::{ entity_action_event::EntityActionEvent, host_world_manager::ActionId, @@ -521,6 +521,7 @@ impl WorldChannel { world_entity: &E, ) -> HostEntity { if let Some(host_entity) = local_world_manager.remove_reserved_host_entity(world_entity) { + info!("World Channel: entity channel opening with reserved host entity: {:?}", host_entity); return host_entity; } else { let host_entity = local_world_manager.generate_host_entity(); diff --git a/socket/server/src/session.rs b/socket/server/src/session.rs index a9ebc8ecd..45b7aa496 100644 --- a/socket/server/src/session.rs +++ b/socket/server/src/session.rs @@ -400,7 +400,11 @@ async fn serve( warn!("Invalid WebRTC session request from {}. Error: unable to decode auth string", remote_addr); } } + } else { + warn!("Invalid WebRTC session request from {}. Error: missing auth string", remote_addr); } + } else { + warn!("Invalid WebRTC session request from {}. Error: missing auth sender", remote_addr); } } @@ -408,13 +412,20 @@ async fn serve( if success && !is_options { success = false; + // info!("reading identity token"); + let identity_token = identity_token_opt.take().unwrap(); + // info!("identity token: {:?}", identity_token); + let mut lines = body.lines(); let buf = RequestBuffer::new(&mut lines); match session_endpoint.http_session_request(buf).await { Ok(resp) => { + + info!("Successful WebRTC session request"); + success = true; let (_head, body) = resp.into_parts(); From fade38731a79da37d10fd232eace5c9d67a18b03 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 12 May 2024 15:42:10 -0500 Subject: [PATCH 79/99] attempting to fix issues with duplicate delegation messages --- client/src/client.rs | 2 + server/src/server.rs | 50 ++++++++++++++++++------ server/src/world/global_world_manager.rs | 33 +++++++++++++--- 3 files changed, 68 insertions(+), 17 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index cecf30c09..70ac00398 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -915,6 +915,7 @@ impl Client { pub(crate) fn publish_entity(&mut self, entity: &E, client_is_origin: bool) { if client_is_origin { + // warn!("sending publish entity message"); let message = EntityEventMessage::new_publish(&self.global_world_manager, entity); self.send_message::(&message); } else { @@ -955,6 +956,7 @@ impl Client { if client_is_origin { // send message to server + // warn!("sending enable delegation for entity message"); let message = EntityEventMessage::new_enable_delegation(&self.global_world_manager, entity); self.send_message::(&message); diff --git a/server/src/server.rs b/server/src/server.rs index abdeb06ac..5c155eda4 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -1240,7 +1240,7 @@ impl Server { world: &mut W, entity: &E, server_origin: bool, - ) { + ) -> bool { if server_origin { // send publish message to entity owner let entity_owner = self.global_world_manager.entity_owner(&entity); @@ -1254,8 +1254,11 @@ impl Server { self.send_message::(&user_key, &message); } - self.global_world_manager.entity_publish(&entity); - world.entity_publish(&self.global_world_manager, &entity); + let result = self.global_world_manager.entity_publish(&entity); + if result { + world.entity_publish(&self.global_world_manager, &entity); + } + return result; } pub(crate) fn unpublish_entity>( @@ -1330,12 +1333,37 @@ impl Server { let Some(entity_owner) = self.global_world_manager.entity_owner(entity) else { panic!("entity should have an owner at this point"); }; - let EntityOwner::ClientPublic(user_key) = entity_owner else { - panic!( - "entity should be owned by a public client at this point. Owner is: {:?}", - entity_owner - ); - }; + let mut owner_user_key; + match entity_owner { + EntityOwner::Client(user_key) => { + owner_user_key = user_key; + warn!( + "entity should be owned by a public client at this point. Owner is: {:?}", + entity_owner + ); + + // publishing here to ensure that the entity is in the correct state .. + // TODO: this is probably a bad idea somehow! this is hacky + // instead, should rely on client message coming through at the appropriate time to publish the entity before this.. + let result = self.global_world_manager.entity_publish(&entity); + if result { + world.entity_publish(&self.global_world_manager, &entity); + } else { + warn!("failed to publish entity before enabling delegation"); + return; + } + } + EntityOwner::ClientPublic(user_key) => { + owner_user_key = user_key; + } + _owner => { + panic!( + "entity should be owned by a public client at this point. Owner is: {:?}", + entity_owner + ); + } + } + let user_key = owner_user_key; self.global_world_manager.migrate_entity_to_server(&entity); // we set this to true immediately since it's already being replicated out to the remote @@ -1982,7 +2010,7 @@ impl Server { for response_event in deferred_events { match response_event { EntityResponseEvent::PublishEntity(entity) => { - // info!("received publish entity message!"); + info!("received publish entity message!"); self.publish_entity(world, &entity, false); self.incoming_events.push_publish(user_key, &entity); } @@ -1991,7 +2019,7 @@ impl Server { self.incoming_events.push_unpublish(user_key, &entity); } EntityResponseEvent::EnableDelegationEntity(entity) => { - // info!("received enable delegation entity message!"); + info!("received enable delegation entity message!"); self.entity_enable_delegation(world, &entity, Some(*user_key)); self.incoming_events.push_delegate(user_key, &entity); } diff --git a/server/src/world/global_world_manager.rs b/server/src/world/global_world_manager.rs index a367c2d32..b524d9f9b 100644 --- a/server/src/world/global_world_manager.rs +++ b/server/src/world/global_world_manager.rs @@ -4,6 +4,8 @@ use std::{ sync::{Arc, RwLock}, }; +use log::{info, warn}; + use naia_shared::{ BigMap, BigMapKey, ComponentKind, EntityAndGlobalEntityConverter, EntityAuthAccessor, EntityAuthStatus, EntityDoesNotExistError, GlobalDiffHandler, GlobalEntity, @@ -135,15 +137,34 @@ impl GlobalWorldManager { // Public - pub(crate) fn entity_publish(&mut self, entity: &E) { + pub(crate) fn entity_publish(&mut self, entity: &E) -> bool { let Some(record) = self.entity_records.get_mut(entity) else { panic!("entity record does not exist!"); }; - if let EntityOwner::Client(user_key) = record.owner { - record.owner = EntityOwner::ClientPublic(user_key); - record.replication_config = ReplicationConfig::Public; - } else { - panic!("Can only publish an Entity that is owned by a Client!"); + + match record.owner { + EntityOwner::Local => { + panic!("Can only publish an Entity that is owned by a Client! Current owner: {:?}", record.owner); + } + EntityOwner::Server => { + warn!("Can only publish an Entity that is owned by a Client! Current owner: {:?}", record.owner); + return false; + } + EntityOwner::ClientWaiting(user_key) => { + panic!("Attempting to publish an Entity that is waiting for a Client to take ownership"); + } + EntityOwner::Client(user_key) => { + // info!("Publishing Entity owned by User: {:?}", user_key); + record.owner = EntityOwner::ClientPublic(user_key); + record.replication_config = ReplicationConfig::Public; + return true; + } + EntityOwner::ClientPublic(user_key) => { + warn!("Published Entity is being published again!"); + record.owner = EntityOwner::ClientPublic(user_key); + record.replication_config = ReplicationConfig::Public; + return true; + } } } From 2416dd9ec32a14729a5f2cab7ff11c3a2a8265cd Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 17 May 2024 14:43:32 -0500 Subject: [PATCH 80/99] cleanup --- client/src/handshake/advanced_handshaker.rs | 6 +++--- client/src/handshake/mod.rs | 2 +- socket/server/src/socket.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/client/src/handshake/advanced_handshaker.rs b/client/src/handshake/advanced_handshaker.rs index bed16f743..3c2e00811 100644 --- a/client/src/handshake/advanced_handshaker.rs +++ b/client/src/handshake/advanced_handshaker.rs @@ -58,9 +58,9 @@ impl Handshaker for HandshakeManager { self.identity_token = Some(identity_token); } - fn is_connected(&self) -> bool { - self.connection_state == HandshakeState::Connected - } + // fn is_connected(&self) -> bool { + // self.connection_state == HandshakeState::Connected + // } // Give handshake manager the opportunity to send out messages to the server fn send(&mut self) -> Option { diff --git a/client/src/handshake/mod.rs b/client/src/handshake/mod.rs index 84c5fe052..7f338d2ef 100644 --- a/client/src/handshake/mod.rs +++ b/client/src/handshake/mod.rs @@ -20,7 +20,7 @@ pub enum HandshakeResult { pub trait Handshaker: Send + Sync { fn set_identity_token(&mut self, identity_token: IdentityToken); - fn is_connected(&self) -> bool; + // fn is_connected(&self) -> bool; fn send(&mut self) -> Option; fn recv(&mut self, reader: &mut BitReader) -> Option; fn write_disconnect(&self) -> BitWriter; diff --git a/socket/server/src/socket.rs b/socket/server/src/socket.rs index 394de256e..78033d513 100644 --- a/socket/server/src/socket.rs +++ b/socket/server/src/socket.rs @@ -49,8 +49,8 @@ impl Socket { Box, Box, ) { - let (from_client_auth_sender, from_client_auth_receiver) = smol::channel::unbounded(); - let (to_session_all_auth_sender, to_session_all_auth_receiver) = smol::channel::unbounded(); + let (from_client_auth_sender, from_client_auth_receiver) = channel::unbounded(); + let (to_session_all_auth_sender, to_session_all_auth_receiver) = channel::unbounded(); let from_client_auth_sender = Some(from_client_auth_sender); let to_session_all_auth_receiver = Some(to_session_all_auth_receiver); From 522a5a31d5b24694997a75333797f0103cc08f2b Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 17 May 2024 16:35:49 -0500 Subject: [PATCH 81/99] cleanup --- server/src/server.rs | 2 +- server/src/world/global_world_manager.rs | 4 ++-- socket/server/src/socket.rs | 18 ++++++++---------- 3 files changed, 11 insertions(+), 13 deletions(-) diff --git a/server/src/server.rs b/server/src/server.rs index 5c155eda4..b09f18c60 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -1333,7 +1333,7 @@ impl Server { let Some(entity_owner) = self.global_world_manager.entity_owner(entity) else { panic!("entity should have an owner at this point"); }; - let mut owner_user_key; + let owner_user_key; match entity_owner { EntityOwner::Client(user_key) => { owner_user_key = user_key; diff --git a/server/src/world/global_world_manager.rs b/server/src/world/global_world_manager.rs index b524d9f9b..67ffd5410 100644 --- a/server/src/world/global_world_manager.rs +++ b/server/src/world/global_world_manager.rs @@ -4,7 +4,7 @@ use std::{ sync::{Arc, RwLock}, }; -use log::{info, warn}; +use log::warn; use naia_shared::{ BigMap, BigMapKey, ComponentKind, EntityAndGlobalEntityConverter, EntityAuthAccessor, @@ -150,7 +150,7 @@ impl GlobalWorldManager { warn!("Can only publish an Entity that is owned by a Client! Current owner: {:?}", record.owner); return false; } - EntityOwner::ClientWaiting(user_key) => { + EntityOwner::ClientWaiting(_user_key) => { panic!("Attempting to publish an Entity that is waiting for a Client to take ownership"); } EntityOwner::Client(user_key) => { diff --git a/socket/server/src/socket.rs b/socket/server/src/socket.rs index 78033d513..0b0b48731 100644 --- a/socket/server/src/socket.rs +++ b/socket/server/src/socket.rs @@ -80,18 +80,18 @@ impl Socket { server_addrs: &ServerAddrs, config: &SocketConfig, from_client_auth_sender: Option< - smol::channel::Sender), NaiaServerSocketError>>, + channel::Sender), NaiaServerSocketError>>, >, to_session_all_auth_receiver: Option< - smol::channel::Receiver<(SocketAddr, Option)>, + channel::Receiver<(SocketAddr, Option)>, >, ) -> ( - smol::channel::Receiver), NaiaServerSocketError>>, - smol::channel::Receiver)>>, + channel::Receiver), NaiaServerSocketError>>, + channel::Receiver)>>, ) { // Set up receiver loop - let (from_client_sender, from_client_receiver) = smol::channel::unbounded(); - let (sender_sender, sender_receiver) = smol::channel::unbounded(); + let (from_client_sender, from_client_receiver) = channel::unbounded(); + let (sender_sender, sender_receiver) = channel::unbounded(); let server_addrs_clone = server_addrs.clone(); let config_clone = config.clone(); @@ -122,10 +122,8 @@ impl Socket { fn setup_sender_loop( config: &SocketConfig, - from_client_receiver: smol::channel::Receiver< - Result<(SocketAddr, Box<[u8]>), NaiaServerSocketError>, - >, - sender_receiver: smol::channel::Receiver)>>, + from_client_receiver: channel::Receiver), NaiaServerSocketError>>, + sender_receiver: channel::Receiver)>>, ) -> (Box, Box) { // Set up sender loop let (to_client_sender, to_client_receiver) = channel::unbounded(); From ac53b326d3ff11327f80826ef0cde346d69dc264 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 17 May 2024 17:48:26 -0500 Subject: [PATCH 82/99] bubble up error on socket connect --- socket/client/src/backends/native/socket.rs | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index f03d7dccb..8c5b7275e 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -1,3 +1,5 @@ +use log::warn; + use naia_socket_shared::{parse_server_url, SocketConfig}; use webrtc_unreliable_client::Socket as RTCSocket; @@ -89,7 +91,12 @@ impl Socket { let (socket, io) = RTCSocket::new(); get_runtime() - .spawn(async move { socket.connect(&server_session_string, auth_bytes_opt, auth_headers_opt).await }); + .spawn(async move { + let result = socket.connect(&server_session_string, auth_bytes_opt, auth_headers_opt).await; + if let Err(e) = result { + warn!("Error connecting to server: {:?}", e); + } + }); // Setup Packet Sender let packet_sender_impl = PacketSenderImpl::new( From 1d9366ac3a2c3cdf61875eb29fab63d9609311f9 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 24 May 2024 05:00:43 -0500 Subject: [PATCH 83/99] cargo fmt --- adapters/bevy/client/src/events.rs | 4 +-- client/src/client.rs | 4 +-- client/src/connection/time_manager.rs | 5 +++- client/src/transport/webrtc.rs | 14 +++++++--- server/src/server.rs | 14 +++++----- server/src/world/global_world_manager.rs | 10 +++++-- shared/src/connection/base_connection.rs | 3 ++- shared/src/key_generator.rs | 1 - shared/src/world/entity/entity_converters.rs | 4 +-- shared/src/world/host/world_channel.rs | 6 ++++- shared/src/world/local_world_manager.rs | 1 - socket/client/src/backends/miniquad/socket.rs | 13 +++++++--- socket/client/src/backends/native/socket.rs | 26 ++++++++++++------- .../src/backends/wasm_bindgen/socket.rs | 15 +++++++---- .../client/src/conditioned_packet_receiver.rs | 2 +- .../server/src/conditioned_packet_receiver.rs | 2 +- socket/server/src/session.rs | 11 +++++--- socket/server/src/socket.rs | 4 ++- 18 files changed, 90 insertions(+), 49 deletions(-) diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 117e7fc43..eb998148a 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -295,12 +295,12 @@ impl EntityAuthResetEvent { // InsertComponentEvent #[derive(Event, Clone)] -pub struct InsertComponentEvents { +pub struct InsertComponentEvents { inner: HashMap>, phantom_t: PhantomData, } -impl InsertComponentEvents { +impl InsertComponentEvents { pub fn new(inner: HashMap>) -> Self { Self { inner, diff --git a/client/src/client.rs b/client/src/client.rs index 70ac00398..fb0f13b3c 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -111,8 +111,8 @@ impl Client { if let Some(auth_headers) = &self.auth_headers { // connect with auth & headers let boxed_socket: Box = socket.into(); - let (id_receiver, packet_sender, packet_receiver) = - boxed_socket.connect_with_auth_and_headers(auth_bytes.clone(), auth_headers.clone()); + let (id_receiver, packet_sender, packet_receiver) = boxed_socket + .connect_with_auth_and_headers(auth_bytes.clone(), auth_headers.clone()); self.io.load(id_receiver, packet_sender, packet_receiver); } else { // connect with auth diff --git a/client/src/connection/time_manager.rs b/client/src/connection/time_manager.rs index 7f801a98e..9f3f02885 100644 --- a/client/src/connection/time_manager.rs +++ b/client/src/connection/time_manager.rs @@ -214,7 +214,10 @@ impl TimeManager { self.instant_from_interp(self.server_receivable_tick, server_receivable_interp); } - pub(crate) fn collect_ticks(&mut self, now: &Instant) -> (Option<(Tick, Tick)>, Option<(Tick, Tick)>) { + pub(crate) fn collect_ticks( + &mut self, + now: &Instant, + ) -> (Option<(Tick, Tick)>, Option<(Tick, Tick)>) { // updates client_receiving_tick // returns (Some(start_tick, end_tick), None) if a client_receiving_tick has incremented // returns (None, Some(start_tick, end_tick)) if a client_sending_tick or server_receivable_tick has incremented diff --git a/client/src/transport/webrtc.rs b/client/src/transport/webrtc.rs index 6324ecc5c..a8783fbbc 100644 --- a/client/src/transport/webrtc.rs +++ b/client/src/transport/webrtc.rs @@ -105,8 +105,11 @@ impl TransportSocket for Socket { Box, Box, ) { - let (id_receiver, inner_sender, inner_receiver) = - ClientSocket::connect_with_auth_headers(&self.server_session_url, &self.config, auth_headers); + let (id_receiver, inner_sender, inner_receiver) = ClientSocket::connect_with_auth_headers( + &self.server_session_url, + &self.config, + auth_headers, + ); return ( Box::new(id_receiver), Box::new(inner_sender), @@ -123,7 +126,12 @@ impl TransportSocket for Socket { Box, ) { let (id_receiver, inner_sender, inner_receiver) = - ClientSocket::connect_with_auth_and_headers(&self.server_session_url, &self.config, auth_bytes, auth_headers); + ClientSocket::connect_with_auth_and_headers( + &self.server_session_url, + &self.config, + auth_bytes, + auth_headers, + ); return ( Box::new(id_receiver), Box::new(inner_sender), diff --git a/server/src/server.rs b/server/src/server.rs index b09f18c60..37fbb9b6c 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -139,7 +139,6 @@ impl Server { /// Must be called regularly, maintains connection to and receives messages /// from all Clients pub fn receive>(&mut self, world: W) -> Events { - let now = Instant::now(); // Need to run this to maintain connection with all clients, and receive packets @@ -1699,11 +1698,7 @@ impl Server { // Private methods /// Maintain connection with a client and read all incoming packet data - fn maintain_socket>( - &mut self, - mut world: W, - now: &Instant, - ) { + fn maintain_socket>(&mut self, mut world: W, now: &Instant) { self.handle_disconnects(&mut world); self.handle_heartbeats(); self.handle_pings(); @@ -1897,7 +1892,12 @@ impl Server { return Ok(()); } - fn process_packets>(&mut self, address: &SocketAddr, world: &mut W, now: &Instant) { + fn process_packets>( + &mut self, + address: &SocketAddr, + world: &mut W, + now: &Instant, + ) { // Packets requiring established connection let (user_key, response_events) = { let Some(connection) = self.user_connections.get_mut(address) else { diff --git a/server/src/world/global_world_manager.rs b/server/src/world/global_world_manager.rs index 67ffd5410..fed0dcdee 100644 --- a/server/src/world/global_world_manager.rs +++ b/server/src/world/global_world_manager.rs @@ -144,10 +144,16 @@ impl GlobalWorldManager { match record.owner { EntityOwner::Local => { - panic!("Can only publish an Entity that is owned by a Client! Current owner: {:?}", record.owner); + panic!( + "Can only publish an Entity that is owned by a Client! Current owner: {:?}", + record.owner + ); } EntityOwner::Server => { - warn!("Can only publish an Entity that is owned by a Client! Current owner: {:?}", record.owner); + warn!( + "Can only publish an Entity that is owned by a Client! Current owner: {:?}", + record.owner + ); return false; } EntityOwner::ClientWaiting(_user_key) => { diff --git a/shared/src/connection/base_connection.rs b/shared/src/connection/base_connection.rs index 5afea533f..af0848474 100644 --- a/shared/src/connection/base_connection.rs +++ b/shared/src/connection/base_connection.rs @@ -118,7 +118,8 @@ impl BaseConnection { } pub fn collect_messages(&mut self, now: &Instant, rtt_millis: &f32) { - self.host_world_manager.handle_dropped_packets(now, rtt_millis); + self.host_world_manager + .handle_dropped_packets(now, rtt_millis); self.message_manager .collect_outgoing_messages(now, rtt_millis); } diff --git a/shared/src/key_generator.rs b/shared/src/key_generator.rs index 958fea0f6..a927021a0 100644 --- a/shared/src/key_generator.rs +++ b/shared/src/key_generator.rs @@ -23,7 +23,6 @@ impl + Into + Copy> KeyGenerator { } /// Get a new, unused key pub fn generate(&mut self) -> K { - let now = Instant::now(); // Check whether we can recycle any keys diff --git a/shared/src/world/entity/entity_converters.rs b/shared/src/world/entity/entity_converters.rs index 49b2edfd2..88e8776f2 100644 --- a/shared/src/world/entity/entity_converters.rs +++ b/shared/src/world/entity/entity_converters.rs @@ -337,9 +337,7 @@ impl<'a, 'b, E: Copy + Eq + Hash> LocalEntityAndGlobalEntityConverterMut return result; } - let host_entity = self - .local_world_manager - .host_reserve_entity(&entity); + let host_entity = self.local_world_manager.host_reserve_entity(&entity); warn!("get_or_reserve_entity(): entity is not owned by user, attempting to reserve. HostEntity: {:?}", host_entity); return Ok(host_entity.copy_to_owned()); diff --git a/shared/src/world/host/world_channel.rs b/shared/src/world/host/world_channel.rs index 052eabe24..0859419a5 100644 --- a/shared/src/world/host/world_channel.rs +++ b/shared/src/world/host/world_channel.rs @@ -256,6 +256,7 @@ impl WorldChannel { entity: &E, ) { if !self.host_world.contains_key(entity) { + // I hit this once, after despawning a ChangelistEntry panic!("World Channel: cannot untrack remote entity that doesn't exist"); } @@ -521,7 +522,10 @@ impl WorldChannel { world_entity: &E, ) -> HostEntity { if let Some(host_entity) = local_world_manager.remove_reserved_host_entity(world_entity) { - info!("World Channel: entity channel opening with reserved host entity: {:?}", host_entity); + info!( + "World Channel: entity channel opening with reserved host entity: {:?}", + host_entity + ); return host_entity; } else { let host_entity = local_world_manager.generate_host_entity(); diff --git a/shared/src/world/local_world_manager.rs b/shared/src/world/local_world_manager.rs index 9f5ba85ba..e98ddf30f 100644 --- a/shared/src/world/local_world_manager.rs +++ b/shared/src/world/local_world_manager.rs @@ -51,7 +51,6 @@ impl LocalWorldManager { } fn process_reserved_entity_timeouts(&mut self) { - let now = Instant::now(); loop { diff --git a/socket/client/src/backends/miniquad/socket.rs b/socket/client/src/backends/miniquad/socket.rs index 0f1b49cbc..ecb96af78 100644 --- a/socket/client/src/backends/miniquad/socket.rs +++ b/socket/client/src/backends/miniquad/socket.rs @@ -48,7 +48,7 @@ impl Socket { pub fn connect_with_auth_headers( server_session_url: &str, config: &SocketConfig, - auth_headers: Vec<(String, String)> + auth_headers: Vec<(String, String)>, ) -> ( Box, Box, @@ -62,13 +62,18 @@ impl Socket { server_session_url: &str, config: &SocketConfig, auth_bytes: Vec, - auth_headers: Vec<(String, String)> + auth_headers: Vec<(String, String)>, ) -> ( Box, Box, Box, ) { - return Self::connect_inner(server_session_url, config, Some(auth_bytes), Some(auth_headers)); + return Self::connect_inner( + server_session_url, + config, + Some(auth_bytes), + Some(auth_headers), + ); } /// Connects to the given server address @@ -76,7 +81,7 @@ impl Socket { server_session_url: &str, config: &SocketConfig, auth_bytes_opt: Option>, - auth_headers_opt: Option> + auth_headers_opt: Option>, ) -> ( Box, Box, diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 8c5b7275e..62a167c5f 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -48,7 +48,7 @@ impl Socket { pub fn connect_with_auth_headers( server_session_url: &str, config: &SocketConfig, - auth_headers: Vec<(String, String)> + auth_headers: Vec<(String, String)>, ) -> ( Box, Box, @@ -62,13 +62,18 @@ impl Socket { server_session_url: &str, config: &SocketConfig, auth_bytes: Vec, - auth_headers: Vec<(String, String)> + auth_headers: Vec<(String, String)>, ) -> ( Box, Box, Box, ) { - return Self::connect_inner(server_session_url, config, Some(auth_bytes), Some(auth_headers)); + return Self::connect_inner( + server_session_url, + config, + Some(auth_bytes), + Some(auth_headers), + ); } /// Connects to the given server address @@ -90,13 +95,14 @@ impl Socket { let conditioner_config = config.link_condition.clone(); let (socket, io) = RTCSocket::new(); - get_runtime() - .spawn(async move { - let result = socket.connect(&server_session_string, auth_bytes_opt, auth_headers_opt).await; - if let Err(e) = result { - warn!("Error connecting to server: {:?}", e); - } - }); + get_runtime().spawn(async move { + let result = socket + .connect(&server_session_string, auth_bytes_opt, auth_headers_opt) + .await; + if let Err(e) = result { + warn!("Error connecting to server: {:?}", e); + } + }); // Setup Packet Sender let packet_sender_impl = PacketSenderImpl::new( diff --git a/socket/client/src/backends/wasm_bindgen/socket.rs b/socket/client/src/backends/wasm_bindgen/socket.rs index dc9abc542..0b779c158 100644 --- a/socket/client/src/backends/wasm_bindgen/socket.rs +++ b/socket/client/src/backends/wasm_bindgen/socket.rs @@ -43,7 +43,7 @@ impl Socket { pub fn connect_with_auth_headers( server_session_url: &str, config: &SocketConfig, - auth_headers: Vec<(String, String)> + auth_headers: Vec<(String, String)>, ) -> ( Box, Box, @@ -52,19 +52,23 @@ impl Socket { return Self::connect_inner(server_session_url, config, None, Some(auth_headers)); } - /// Connects to the given server address with authentication pub fn connect_with_auth_and_headers( server_session_url: &str, config: &SocketConfig, auth_bytes: Vec, - auth_headers: Vec<(String, String)> + auth_headers: Vec<(String, String)>, ) -> ( Box, Box, Box, ) { - return Self::connect_inner(server_session_url, config, Some(auth_bytes), Some(auth_headers)); + return Self::connect_inner( + server_session_url, + config, + Some(auth_bytes), + Some(auth_headers), + ); } /// Connects to the given server address @@ -78,7 +82,8 @@ impl Socket { Box, Box, ) { - let data_channel = DataChannel::new(config, server_session_url, auth_bytes_opt, auth_headers_opt); + let data_channel = + DataChannel::new(config, server_session_url, auth_bytes_opt, auth_headers_opt); let data_port = data_channel.data_port(); let addr_cell = data_channel.addr_cell(); diff --git a/socket/client/src/conditioned_packet_receiver.rs b/socket/client/src/conditioned_packet_receiver.rs index e2979992f..3cd662e51 100644 --- a/socket/client/src/conditioned_packet_receiver.rs +++ b/socket/client/src/conditioned_packet_receiver.rs @@ -1,4 +1,4 @@ -use naia_socket_shared::{Instant, link_condition_logic, LinkConditionerConfig, TimeQueue}; +use naia_socket_shared::{link_condition_logic, Instant, LinkConditionerConfig, TimeQueue}; use super::{ error::NaiaClientSocketError, packet_receiver::PacketReceiver, server_addr::ServerAddr, diff --git a/socket/server/src/conditioned_packet_receiver.rs b/socket/server/src/conditioned_packet_receiver.rs index 8f9fff7cd..6728b36f6 100644 --- a/socket/server/src/conditioned_packet_receiver.rs +++ b/socket/server/src/conditioned_packet_receiver.rs @@ -2,7 +2,7 @@ use std::net::SocketAddr; use smol::channel::Receiver; -use naia_socket_shared::{Instant, link_condition_logic, LinkConditionerConfig, TimeQueue}; +use naia_socket_shared::{link_condition_logic, Instant, LinkConditionerConfig, TimeQueue}; use super::{error::NaiaServerSocketError, packet_receiver::PacketReceiver}; diff --git a/socket/server/src/session.rs b/socket/server/src/session.rs index 45b7aa496..9eb8f118c 100644 --- a/socket/server/src/session.rs +++ b/socket/server/src/session.rs @@ -401,10 +401,16 @@ async fn serve( } } } else { - warn!("Invalid WebRTC session request from {}. Error: missing auth string", remote_addr); + warn!( + "Invalid WebRTC session request from {}. Error: missing auth string", + remote_addr + ); } } else { - warn!("Invalid WebRTC session request from {}. Error: missing auth sender", remote_addr); + warn!( + "Invalid WebRTC session request from {}. Error: missing auth sender", + remote_addr + ); } } @@ -423,7 +429,6 @@ async fn serve( match session_endpoint.http_session_request(buf).await { Ok(resp) => { - info!("Successful WebRTC session request"); success = true; diff --git a/socket/server/src/socket.rs b/socket/server/src/socket.rs index 0b0b48731..890160120 100644 --- a/socket/server/src/socket.rs +++ b/socket/server/src/socket.rs @@ -122,7 +122,9 @@ impl Socket { fn setup_sender_loop( config: &SocketConfig, - from_client_receiver: channel::Receiver), NaiaServerSocketError>>, + from_client_receiver: channel::Receiver< + Result<(SocketAddr, Box<[u8]>), NaiaServerSocketError>, + >, sender_receiver: channel::Receiver)>>, ) -> (Box, Box) { // Set up sender loop From 68f5ccd5328e71444614d0c74d5d01760363d423 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sat, 25 May 2024 02:23:46 -0500 Subject: [PATCH 84/99] - get rid of superfluous logging message - SerdeInteger now implements Hash --- adapters/bevy/shared/src/lib.rs | 2 +- shared/serde/src/integer.rs | 2 +- socket/server/src/session.rs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 86f89383e..07fde8c7f 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -1,5 +1,5 @@ pub use naia_shared::{ - sequence_greater_than, BitReader, BitWrite, BitWriter, Channel, ChannelDirection, ChannelKind, + sequence_greater_than, sequence_less_than, wrapping_diff, BitReader, BitWrite, BitWriter, Channel, ChannelDirection, ChannelKind, ChannelMode, ComponentFieldUpdate, ComponentKind, ComponentKinds, ComponentUpdate, ConstBitLength, DiffMask, EntityAndGlobalEntityConverter, EntityAuthAccessor, EntityAuthStatus, EntityDoesNotExistError, EntityProperty, FakeEntityConverter, GlobalEntity, HostEntity, diff --git a/shared/serde/src/integer.rs b/shared/serde/src/integer.rs index 837621ede..0c7218f99 100644 --- a/shared/serde/src/integer.rs +++ b/shared/serde/src/integer.rs @@ -7,7 +7,7 @@ pub type SignedInteger = SerdeInteger; pub type UnsignedVariableInteger = SerdeInteger; pub type SignedVariableInteger = SerdeInteger; -#[derive(Debug, Clone, Copy, Eq, PartialEq)] +#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)] pub struct SerdeInteger { inner: i128, } diff --git a/socket/server/src/session.rs b/socket/server/src/session.rs index 9eb8f118c..c4244415f 100644 --- a/socket/server/src/session.rs +++ b/socket/server/src/session.rs @@ -429,7 +429,7 @@ async fn serve( match session_endpoint.http_session_request(buf).await { Ok(resp) => { - info!("Successful WebRTC session request"); + // info!("Successful WebRTC session request"); success = true; From 3df5ed8a70526e076569b2b2f7bc779407021ce5 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 7 Jul 2024 13:50:43 -0600 Subject: [PATCH 85/99] minor cleanup --- adapters/bevy/client/src/events.rs | 10 ++++++-- adapters/bevy/shared/src/lib.rs | 24 +++++++++---------- server/src/handshake/advanced_handshaker.rs | 4 ++-- .../src/backends/native/packet_receiver.rs | 2 +- .../backends/wasm_bindgen/packet_receiver.rs | 2 +- socket/client/src/error.rs | 3 --- 6 files changed, 24 insertions(+), 21 deletions(-) diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index eb998148a..0aef47352 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -295,12 +295,12 @@ impl EntityAuthResetEvent { // InsertComponentEvent #[derive(Event, Clone)] -pub struct InsertComponentEvents { +pub struct InsertComponentEvents { inner: HashMap>, phantom_t: PhantomData, } -impl InsertComponentEvents { +impl InsertComponentEvents { pub fn new(inner: HashMap>) -> Self { Self { inner, @@ -391,3 +391,9 @@ impl RemoveComponentEvents { output } } + +impl Clone for RemoveComponentEvents { + fn clone(&self) -> Self { + self.clone_new() + } +} \ No newline at end of file diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 07fde8c7f..113ba2386 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -1,16 +1,16 @@ pub use naia_shared::{ - sequence_greater_than, sequence_less_than, wrapping_diff, BitReader, BitWrite, BitWriter, Channel, ChannelDirection, ChannelKind, - ChannelMode, ComponentFieldUpdate, ComponentKind, ComponentKinds, ComponentUpdate, - ConstBitLength, DiffMask, EntityAndGlobalEntityConverter, EntityAuthAccessor, EntityAuthStatus, - EntityDoesNotExistError, EntityProperty, FakeEntityConverter, GlobalEntity, HostEntity, - HostEntityAuthStatus, LinkConditionerConfig, LocalEntityAndGlobalEntityConverter, - LocalEntityAndGlobalEntityConverterMut, MessageBevy as Message, MessageBuilder, - MessageContainer, MessageKind, MessageKinds, Named, OwnedBitReader, Property, PropertyMutate, - PropertyMutator, Random, ReliableSettings, RemoteEntity, ReplicaDynMut, ReplicaDynRef, - ReplicateBevy as Replicate, ReplicateBuilder, Request, Response, ResponseReceiveKey, - ResponseSendKey, SerdeBevyShared as Serde, SerdeErr, SerdeIntegerConversion, SignedInteger, - SignedVariableInteger, Tick, TickBufferSettings, Timer, UnsignedInteger, - UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, + sequence_greater_than, sequence_less_than, wrapping_diff, BitReader, BitWrite, BitWriter, + Channel, ChannelDirection, ChannelKind, ChannelMode, ComponentFieldUpdate, ComponentKind, + ComponentKinds, ComponentUpdate, ConstBitLength, DiffMask, EntityAndGlobalEntityConverter, + EntityAuthAccessor, EntityAuthStatus, EntityDoesNotExistError, EntityProperty, + FakeEntityConverter, GlobalEntity, HostEntity, HostEntityAuthStatus, LinkConditionerConfig, + LocalEntityAndGlobalEntityConverter, LocalEntityAndGlobalEntityConverterMut, + MessageBevy as Message, MessageBuilder, MessageContainer, MessageKind, MessageKinds, Named, + OwnedBitReader, Property, PropertyMutate, PropertyMutator, Random, ReliableSettings, + RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBevy as Replicate, ReplicateBuilder, + Request, Response, ResponseReceiveKey, ResponseSendKey, SerdeBevyShared as Serde, SerdeErr, + SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, Timer, + UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, }; mod change_detection; diff --git a/server/src/handshake/advanced_handshaker.rs b/server/src/handshake/advanced_handshaker.rs index 55f63851c..2b3d94bcc 100644 --- a/server/src/handshake/advanced_handshaker.rs +++ b/server/src/handshake/advanced_handshaker.rs @@ -1,6 +1,6 @@ use std::{collections::HashMap, net::SocketAddr}; -use log::{info, warn}; +use log::warn; use ring::{hmac, rand}; use naia_server_socket::shared::IdentityToken; @@ -88,7 +88,7 @@ impl Handshaker for HandshakeManager { let writer = self.write_validate_response(); return Ok(HandshakeAction::SendPacket(writer.to_packet())); } else { - info!("checking authenticated users for {}", address); + // info!("checking authenticated users for {}", address); if let Some(user_key) = self.authenticated_and_identified_users.get(address) { let user_key = *user_key; diff --git a/socket/client/src/backends/native/packet_receiver.rs b/socket/client/src/backends/native/packet_receiver.rs index 5586592f0..ed9b2873d 100644 --- a/socket/client/src/backends/native/packet_receiver.rs +++ b/socket/client/src/backends/native/packet_receiver.rs @@ -36,7 +36,7 @@ impl PacketReceiver for PacketReceiverImpl { return Ok(Some(&self.receive_buffer[..length])); } } - Ok(None) + return Ok(None); } /// Get the Server's Socket address diff --git a/socket/client/src/backends/wasm_bindgen/packet_receiver.rs b/socket/client/src/backends/wasm_bindgen/packet_receiver.rs index c0d2f1c0a..7552ca64d 100644 --- a/socket/client/src/backends/wasm_bindgen/packet_receiver.rs +++ b/socket/client/src/backends/wasm_bindgen/packet_receiver.rs @@ -21,7 +21,7 @@ impl PacketReceiverImpl { /// Create a new PacketReceiver, if supplied with the RtcDataChannel and a /// reference to a list of dropped messages pub fn new(data_port: &DataPort, addr_cell: &AddrCell) -> Self { - PacketReceiverImpl { + Self { message_queue: data_port.message_queue(), server_addr: addr_cell.clone(), last_payload: None, diff --git a/socket/client/src/error.rs b/socket/client/src/error.rs index 102854b81..ab49edcf9 100644 --- a/socket/client/src/error.rs +++ b/socket/client/src/error.rs @@ -6,8 +6,6 @@ use std::{error::Error, fmt}; pub enum NaiaClientSocketError { /// A simple error message Message(String), - /// A wrapped error from another library/codebase - Wrapped(Box), /// An error indicating an inability to send to the given address SendError, } @@ -16,7 +14,6 @@ impl fmt::Display for NaiaClientSocketError { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match self { NaiaClientSocketError::Message(msg) => write!(f, "Naia Client Socket Error: {}", msg), - NaiaClientSocketError::Wrapped(boxed_err) => fmt::Display::fmt(boxed_err.as_ref(), f), NaiaClientSocketError::SendError => write!(f, "Naia Client Socket Send Error"), } } From dee86db1c3310a19425b57c4131ad695980c3c84 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 7 Jul 2024 14:33:43 -0600 Subject: [PATCH 86/99] now returning errors from identity receiver in client handshake --- client/src/client.rs | 18 ++++++++----- client/src/connection/io.rs | 23 ++++++++-------- client/src/transport/mod.rs | 5 ++-- client/src/transport/webrtc.rs | 10 +++---- .../backends/miniquad/identity_receiver.rs | 2 +- .../src/backends/native/identity_receiver.rs | 26 ++++++++----------- socket/client/src/backends/native/socket.rs | 6 +---- .../wasm_bindgen/identity_receiver.rs | 17 +++++++----- socket/client/src/identity_receiver.rs | 8 ++++-- socket/client/src/lib.rs | 2 +- 10 files changed, 59 insertions(+), 58 deletions(-) diff --git a/client/src/client.rs b/client/src/client.rs index fb0f13b3c..fbcd2ffb2 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1,7 +1,7 @@ use std::{any::Any, collections::VecDeque, hash::Hash, net::SocketAddr}; use log::{info, warn}; - +use naia_client_socket::IdentityReceiverResult; use naia_shared::{ BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, @@ -1103,12 +1103,16 @@ impl Client { } if !self.io.is_authenticated() { - // info!("Client is not authenticated yet, trying to receive id"); - if let Some(id_token) = self.io.recv_auth() { - // info!("Received IdToken: {:?}, passing to Handshaker", id_token); - self.handshake_manager.set_identity_token(id_token); - } else { - return; + match self.io.recv_auth() { + IdentityReceiverResult::Success(id_token) => { + self.handshake_manager.set_identity_token(id_token); + } + IdentityReceiverResult::Waiting => { + return; + } + IdentityReceiverResult::ErrorResponseCode(code) => { + panic!("Error receiving auth token: {:?}", code); + } } } diff --git a/client/src/connection/io.rs b/client/src/connection/io.rs index cecb9ec34..204bb0cd2 100644 --- a/client/src/connection/io.rs +++ b/client/src/connection/io.rs @@ -1,7 +1,8 @@ use std::{net::SocketAddr, time::Duration}; +use naia_client_socket::IdentityReceiverResult; use naia_shared::{ - BandwidthMonitor, BitReader, CompressionConfig, Decoder, Encoder, IdentityToken, OutgoingPacket, + BandwidthMonitor, BitReader, CompressionConfig, Decoder, Encoder, OutgoingPacket, }; use crate::{ @@ -76,19 +77,19 @@ impl Io { self.authenticated } - pub fn recv_auth(&mut self) -> Option { - // info!("Io::recv_auth() called"); - let id_receiver = self.id_receiver.as_mut()?; - // info!("id_receiver is Some"); - let id_result = id_receiver.receive().ok()?; - // info!("result is Some"); - if id_result.is_some() { - // info!("Received IdToken from IdentityReceiver!"); + pub fn recv_auth(&mut self) -> IdentityReceiverResult { + + let Some(id_receiver) = self.id_receiver.as_mut() else { + return IdentityReceiverResult::Waiting; + }; + + let id_result = id_receiver.receive(); + + if let IdentityReceiverResult::Success(_) = &id_result { self.authenticated = true; self.id_receiver = None; - } else { - // info!("No IdToken available from IdentityReceiver"); } + id_result } diff --git a/client/src/transport/mod.rs b/client/src/transport/mod.rs index 67592d55a..3d2b8a84a 100644 --- a/client/src/transport/mod.rs +++ b/client/src/transport/mod.rs @@ -16,8 +16,7 @@ pub use server_addr::ServerAddr; pub use inner::{IdentityReceiver, PacketReceiver, PacketSender, RecvError, SendError, Socket}; mod inner { - - use naia_client_socket::shared::IdentityToken; + use naia_client_socket::IdentityReceiverResult; use super::ServerAddr; @@ -96,7 +95,7 @@ mod inner { pub trait IdentityReceiver: IdentityReceiverClone + Send + Sync { /// - fn receive(&mut self) -> Result, RecvError>; + fn receive(&mut self) -> IdentityReceiverResult; } /// Used to clone Box diff --git a/client/src/transport/webrtc.rs b/client/src/transport/webrtc.rs index a8783fbbc..c629f7ea7 100644 --- a/client/src/transport/webrtc.rs +++ b/client/src/transport/webrtc.rs @@ -1,8 +1,6 @@ -use naia_shared::{IdentityToken, SocketConfig}; +use naia_shared::SocketConfig; -use naia_client_socket::{ - IdentityReceiver, PacketReceiver, PacketSender, ServerAddr, Socket as ClientSocket, -}; +use naia_client_socket::{IdentityReceiver, IdentityReceiverResult, PacketReceiver, PacketSender, ServerAddr, Socket as ClientSocket}; use super::{ IdentityReceiver as TransportIdentityReceiver, PacketReceiver as TransportReceiver, @@ -54,8 +52,8 @@ impl TransportReceiver for Box { impl TransportIdentityReceiver for Box { /// Receives an IdentityToken from the Client Socket - fn receive(&mut self) -> Result, RecvError> { - self.as_mut().receive().map_err(|_| RecvError) + fn receive(&mut self) -> IdentityReceiverResult { + self.as_mut().receive() } } diff --git a/socket/client/src/backends/miniquad/identity_receiver.rs b/socket/client/src/backends/miniquad/identity_receiver.rs index cbcf838f1..af2283ccb 100644 --- a/socket/client/src/backends/miniquad/identity_receiver.rs +++ b/socket/client/src/backends/miniquad/identity_receiver.rs @@ -8,7 +8,7 @@ use crate::{error::NaiaClientSocketError, identity_receiver::IdentityReceiver}; pub struct IdentityReceiverImpl; impl IdentityReceiver for IdentityReceiverImpl { - fn receive(&mut self) -> Result, NaiaClientSocketError> { + fn receive(&mut self) -> IdentityReceiverResult { unsafe { if let Some(id_cell) = &mut ID_CELL { if let Some(id_token) = id_cell.take() { diff --git a/socket/client/src/backends/native/identity_receiver.rs b/socket/client/src/backends/native/identity_receiver.rs index 8d33c2f84..262923b5a 100644 --- a/socket/client/src/backends/native/identity_receiver.rs +++ b/socket/client/src/backends/native/identity_receiver.rs @@ -2,20 +2,18 @@ use std::sync::{Arc, Mutex}; use tokio::sync::oneshot; -use naia_socket_shared::IdentityToken; - -use crate::{error::NaiaClientSocketError, identity_receiver::IdentityReceiver}; +use crate::{identity_receiver::IdentityReceiver, IdentityReceiverResult}; /// Handles receiving an IdentityToken from the Server through a given Client Socket #[derive(Clone)] pub struct IdentityReceiverImpl { - receiver_channel: Arc>>, + receiver_channel: Arc>>>, } impl IdentityReceiverImpl { /// Create a new IdentityReceiver, if supplied with the Server's address & a /// reference back to the parent Socket - pub fn new(receiver_channel: oneshot::Receiver) -> Self { + pub fn new(receiver_channel: oneshot::Receiver>) -> Self { Self { receiver_channel: Arc::new(Mutex::new(receiver_channel)), } @@ -23,20 +21,18 @@ impl IdentityReceiverImpl { } impl IdentityReceiver for IdentityReceiverImpl { - fn receive(&mut self) -> Result, NaiaClientSocketError> { - // info!("IdentityReceiverImpl::receive - Called"); + fn receive(&mut self) -> IdentityReceiverResult { if let Ok(mut receiver) = self.receiver_channel.lock() { - // info!("IdentityReceiverImpl::receive - Lock acquired"); - if let Ok(token) = receiver.try_recv() { - // info!("IdentityReceiverImpl::receive - Received IdentityToken"); - return Ok(Some(token)); + if let Ok(recv_result) = receiver.try_recv() { + return match recv_result { + Ok(identity_token) => IdentityReceiverResult::Success(identity_token), + Err(error_code) => IdentityReceiverResult::ErrorResponseCode(error_code), + } } else { - // info!("IdentityReceiverImpl::receive - No IdentityToken available"); - return Ok(None); + return IdentityReceiverResult::Waiting; } } else { - // info!("IdentityReceiverImpl::receive - Lock not acquired"); - return Ok(None); + return IdentityReceiverResult::Waiting; } } } diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 62a167c5f..8fdc1065f 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -1,4 +1,3 @@ -use log::warn; use naia_socket_shared::{parse_server_url, SocketConfig}; @@ -96,12 +95,9 @@ impl Socket { let (socket, io) = RTCSocket::new(); get_runtime().spawn(async move { - let result = socket + socket .connect(&server_session_string, auth_bytes_opt, auth_headers_opt) .await; - if let Err(e) = result { - warn!("Error connecting to server: {:?}", e); - } }); // Setup Packet Sender diff --git a/socket/client/src/backends/wasm_bindgen/identity_receiver.rs b/socket/client/src/backends/wasm_bindgen/identity_receiver.rs index 872af9053..e17f7366b 100644 --- a/socket/client/src/backends/wasm_bindgen/identity_receiver.rs +++ b/socket/client/src/backends/wasm_bindgen/identity_receiver.rs @@ -2,12 +2,12 @@ use std::sync::{Arc, Mutex}; use naia_socket_shared::IdentityToken; -use crate::{error::NaiaClientSocketError, identity_receiver::IdentityReceiver}; +use crate::{IdentityReceiverResult, identity_receiver::IdentityReceiver}; /// Handles receiving an IdentityToken from the Server through a given Client Socket #[derive(Clone)] pub struct IdentityReceiverImpl { - id_cell: Arc>>, + id_cell: Arc>>>, } impl IdentityReceiverImpl { @@ -26,22 +26,25 @@ impl IdentityReceiverImpl { .lock() .expect("This should never happen, message_queue should always be available in a single-threaded context"); - *token_guard = Some(id_token); + *token_guard = Some(Ok(id_token)); } } impl IdentityReceiver for IdentityReceiverImpl { - fn receive(&mut self) -> Result, NaiaClientSocketError> { + fn receive(&mut self) -> IdentityReceiverResult { let mut token_guard = self .id_cell .lock() .expect("This should never happen, message_queue should always be available in a single-threaded context"); if token_guard.is_some() { - let token = token_guard.take().unwrap(); - return Ok(Some(token)); + let token_result = token_guard.take().unwrap(); + match token_result { + Ok(token) => return IdentityReceiverResult::Success(token), + Err(error_code) => return IdentityReceiverResult::ErrorResponseCode(error_code), + } } else { - return Ok(None); + return IdentityReceiverResult::Waiting; } } } diff --git a/socket/client/src/identity_receiver.rs b/socket/client/src/identity_receiver.rs index e4a7e021c..5b15fc429 100644 --- a/socket/client/src/identity_receiver.rs +++ b/socket/client/src/identity_receiver.rs @@ -1,11 +1,15 @@ use naia_socket_shared::IdentityToken; -use super::error::NaiaClientSocketError; +pub enum IdentityReceiverResult { + Waiting, + Success(IdentityToken), + ErrorResponseCode(u16), +} /// Used to receive an IdentityToken from the Client Socket pub trait IdentityReceiver: IdentityReceiverClone + Send + Sync { /// Receives an IdentityToken from the Client Socket - fn receive(&mut self) -> Result, NaiaClientSocketError>; + fn receive(&mut self) -> IdentityReceiverResult; } /// Used to clone Box diff --git a/socket/client/src/lib.rs b/socket/client/src/lib.rs index f2732b4da..dc9eb7151 100755 --- a/socket/client/src/lib.rs +++ b/socket/client/src/lib.rs @@ -27,7 +27,7 @@ pub use naia_socket_shared as shared; pub use backends::*; pub use error::NaiaClientSocketError; -pub use identity_receiver::IdentityReceiver; +pub use identity_receiver::{IdentityReceiver, IdentityReceiverResult}; pub use packet_receiver::PacketReceiver; pub use packet_sender::PacketSender; pub use server_addr::ServerAddr; From 22ec966463920bd0fdba6cd38bd19c57dcd23827 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 7 Jul 2024 15:16:45 -0600 Subject: [PATCH 87/99] client handles auth response code, throwing error --- adapters/bevy/client/src/lib.rs | 2 +- client/src/client.rs | 16 +++++++++++++++- client/src/error.rs | 10 ++++++---- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 4245b96a9..8ee584cd3 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -4,7 +4,7 @@ pub use naia_bevy_shared::{ }; pub use naia_client::{ shared::{default_channels, Instant, Message, ResponseReceiveKey}, - transport, ClientConfig, CommandHistory, ReplicationConfig, + transport, ClientConfig, CommandHistory, ReplicationConfig, NaiaClientError, }; pub mod events; diff --git a/client/src/client.rs b/client/src/client.rs index fbcd2ffb2..a48841b78 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1111,7 +1111,19 @@ impl Client { return; } IdentityReceiverResult::ErrorResponseCode(code) => { - panic!("Error receiving auth token: {:?}", code); + + warn!("Authentication error status code: {}", code); + + // reset connection + self.io = Io::new( + &self.client_config.connection.bandwidth_measure_duration, + &self.protocol.compression, + ); + + // push out error + self.incoming_events.push_error(NaiaClientError::IdError(code)); + + return; } } } @@ -1153,6 +1165,8 @@ impl Client { } } } + + return; } fn maintain_connection(&mut self) { diff --git a/client/src/error.rs b/client/src/error.rs index f66725613..2c39aad3a 100644 --- a/client/src/error.rs +++ b/client/src/error.rs @@ -6,6 +6,7 @@ pub enum NaiaClientError { Wrapped(Box), SendError, RecvError, + IdError(u16), } impl NaiaClientError { @@ -17,10 +18,11 @@ impl NaiaClientError { impl fmt::Display for NaiaClientError { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { match self { - NaiaClientError::Message(msg) => write!(f, "Naia Client Error: {}", msg), - NaiaClientError::Wrapped(boxed_err) => fmt::Display::fmt(boxed_err.as_ref(), f), - NaiaClientError::SendError => write!(f, "Naia Client Error: Send Error"), - NaiaClientError::RecvError => write!(f, "Naia Client Error: Recv Error"), + Self::Message(msg) => write!(f, "Naia Client Error: {}", msg), + Self::Wrapped(boxed_err) => fmt::Display::fmt(boxed_err.as_ref(), f), + Self::SendError => write!(f, "Naia Client Error: Send Error"), + Self::RecvError => write!(f, "Naia Client Error: Recv Error"), + Self::IdError(code) => write!(f, "Naia Client Error: Id Error: {}", code), } } } From 12d96fd9c6608a8e541fc58af62e62317237061e Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 12 Jul 2024 12:14:43 -0600 Subject: [PATCH 88/99] get rid of unnecessary naia_derive property --- shared/derive/src/message.rs | 5 ----- 1 file changed, 5 deletions(-) diff --git a/shared/derive/src/message.rs b/shared/derive/src/message.rs index bbab3d2f0..869004bfa 100644 --- a/shared/derive/src/message.rs +++ b/shared/derive/src/message.rs @@ -543,7 +543,6 @@ fn get_variable_name_for_unnamed_field(index: usize, span: Span) -> Ident { pub struct EntityProperty { pub variable_name: Ident, - pub uppercase_variable_name: Ident, } pub struct Normal { @@ -561,10 +560,6 @@ impl Field { pub fn entity_property(variable_name: Ident) -> Self { Self::EntityProperty(EntityProperty { variable_name: variable_name.clone(), - uppercase_variable_name: Ident::new( - variable_name.to_string().to_uppercase().as_str(), - Span::call_site(), - ), }) } From fbf988cbb4a2da9646579431466c95f2241de3b8 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 15 Jul 2024 17:37:56 -0600 Subject: [PATCH 89/99] cargo fmt --- adapters/bevy/client/src/events.rs | 2 +- adapters/bevy/client/src/lib.rs | 2 +- client/src/client.rs | 4 ++-- client/src/connection/io.rs | 1 - client/src/transport/webrtc.rs | 5 ++++- socket/client/src/backends/native/identity_receiver.rs | 2 +- socket/client/src/backends/native/socket.rs | 1 - socket/client/src/backends/wasm_bindgen/identity_receiver.rs | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/adapters/bevy/client/src/events.rs b/adapters/bevy/client/src/events.rs index 0aef47352..70de733d1 100644 --- a/adapters/bevy/client/src/events.rs +++ b/adapters/bevy/client/src/events.rs @@ -396,4 +396,4 @@ impl Clone for RemoveComponentEvents { fn clone(&self) -> Self { self.clone_new() } -} \ No newline at end of file +} diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 8ee584cd3..117f90d03 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -4,7 +4,7 @@ pub use naia_bevy_shared::{ }; pub use naia_client::{ shared::{default_channels, Instant, Message, ResponseReceiveKey}, - transport, ClientConfig, CommandHistory, ReplicationConfig, NaiaClientError, + transport, ClientConfig, CommandHistory, NaiaClientError, ReplicationConfig, }; pub mod events; diff --git a/client/src/client.rs b/client/src/client.rs index a48841b78..f36c9589c 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -1111,7 +1111,6 @@ impl Client { return; } IdentityReceiverResult::ErrorResponseCode(code) => { - warn!("Authentication error status code: {}", code); // reset connection @@ -1121,7 +1120,8 @@ impl Client { ); // push out error - self.incoming_events.push_error(NaiaClientError::IdError(code)); + self.incoming_events + .push_error(NaiaClientError::IdError(code)); return; } diff --git a/client/src/connection/io.rs b/client/src/connection/io.rs index 204bb0cd2..290a557e3 100644 --- a/client/src/connection/io.rs +++ b/client/src/connection/io.rs @@ -78,7 +78,6 @@ impl Io { } pub fn recv_auth(&mut self) -> IdentityReceiverResult { - let Some(id_receiver) = self.id_receiver.as_mut() else { return IdentityReceiverResult::Waiting; }; diff --git a/client/src/transport/webrtc.rs b/client/src/transport/webrtc.rs index c629f7ea7..4c3b6f909 100644 --- a/client/src/transport/webrtc.rs +++ b/client/src/transport/webrtc.rs @@ -1,6 +1,9 @@ use naia_shared::SocketConfig; -use naia_client_socket::{IdentityReceiver, IdentityReceiverResult, PacketReceiver, PacketSender, ServerAddr, Socket as ClientSocket}; +use naia_client_socket::{ + IdentityReceiver, IdentityReceiverResult, PacketReceiver, PacketSender, ServerAddr, + Socket as ClientSocket, +}; use super::{ IdentityReceiver as TransportIdentityReceiver, PacketReceiver as TransportReceiver, diff --git a/socket/client/src/backends/native/identity_receiver.rs b/socket/client/src/backends/native/identity_receiver.rs index 262923b5a..4d5ca5d73 100644 --- a/socket/client/src/backends/native/identity_receiver.rs +++ b/socket/client/src/backends/native/identity_receiver.rs @@ -27,7 +27,7 @@ impl IdentityReceiver for IdentityReceiverImpl { return match recv_result { Ok(identity_token) => IdentityReceiverResult::Success(identity_token), Err(error_code) => IdentityReceiverResult::ErrorResponseCode(error_code), - } + }; } else { return IdentityReceiverResult::Waiting; } diff --git a/socket/client/src/backends/native/socket.rs b/socket/client/src/backends/native/socket.rs index 8fdc1065f..aa754739a 100644 --- a/socket/client/src/backends/native/socket.rs +++ b/socket/client/src/backends/native/socket.rs @@ -1,4 +1,3 @@ - use naia_socket_shared::{parse_server_url, SocketConfig}; use webrtc_unreliable_client::Socket as RTCSocket; diff --git a/socket/client/src/backends/wasm_bindgen/identity_receiver.rs b/socket/client/src/backends/wasm_bindgen/identity_receiver.rs index e17f7366b..14f16f994 100644 --- a/socket/client/src/backends/wasm_bindgen/identity_receiver.rs +++ b/socket/client/src/backends/wasm_bindgen/identity_receiver.rs @@ -2,7 +2,7 @@ use std::sync::{Arc, Mutex}; use naia_socket_shared::IdentityToken; -use crate::{IdentityReceiverResult, identity_receiver::IdentityReceiver}; +use crate::{identity_receiver::IdentityReceiver, IdentityReceiverResult}; /// Handles receiving an IdentityToken from the Server through a given Client Socket #[derive(Clone)] From 053b5286c2c618171e88b221f12e02544fe5dcf7 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 15 Jul 2024 17:48:35 -0600 Subject: [PATCH 90/99] added client component events helper systems in naia_bevy_client --- adapters/bevy/client/src/component_events.rs | 238 +++++++++++++++++++ adapters/bevy/client/src/lib.rs | 1 + 2 files changed, 239 insertions(+) create mode 100644 adapters/bevy/client/src/component_events.rs diff --git a/adapters/bevy/client/src/component_events.rs b/adapters/bevy/client/src/component_events.rs new file mode 100644 index 000000000..3c3b021eb --- /dev/null +++ b/adapters/bevy/client/src/component_events.rs @@ -0,0 +1,238 @@ +use bevy_app::App; +use bevy_ecs::{ + change_detection::Mut, + entity::Entity, + event::{Event, EventReader, EventWriter}, + prelude::{Resource, World as BevyWorld}, + system::SystemState, +}; + +use crate::{ + events::{InsertComponentEvents, RemoveComponentEvents, UpdateComponentEvents}, + Replicate, Tick, +}; + +// ComponentEvent +pub enum ComponentEvents { + Insert(InsertComponentEvents), + Update(UpdateComponentEvents), + Remove(RemoveComponentEvents), +} + +impl ComponentEvents { + pub fn is_insert(&self) -> bool { + match self { + Self::Insert(_) => true, + _ => false, + } + } + + pub fn as_insert(&self) -> &InsertComponentEvents { + match self { + Self::Insert(events) => events, + _ => panic!("ComponentEvents is not Insert"), + } + } + + pub fn process(&self, world: &mut BevyWorld) { + match self { + Self::Insert(events) => insert_component_event::(world, &events), + Self::Update(events) => update_component_event::(world, &events), + Self::Remove(events) => remove_component_event::(world, &events), + } + } +} + +#[derive(Event)] +pub struct InsertComponentEvent { + pub entity: Entity, + phantom_t: std::marker::PhantomData, + phantom_c: std::marker::PhantomData, +} + +impl InsertComponentEvent { + pub fn new(entity: Entity) -> Self { + Self { + entity, + phantom_t: std::marker::PhantomData, + phantom_c: std::marker::PhantomData, + } + } +} + +#[derive(Event)] +pub struct UpdateComponentEvent { + pub tick: Tick, + pub entity: Entity, + phantom_t: std::marker::PhantomData, + phantom_c: std::marker::PhantomData, +} + +impl UpdateComponentEvent { + pub fn new(tick: Tick, entity: Entity) -> Self { + Self { + tick, + entity, + phantom_t: std::marker::PhantomData, + phantom_c: std::marker::PhantomData, + } + } +} + +#[derive(Event)] +pub struct RemoveComponentEvent { + pub entity: Entity, + phantom_t: std::marker::PhantomData, + pub component: C, +} + +impl RemoveComponentEvent { + pub fn new(entity: Entity, component: C) -> Self { + Self { + entity, + phantom_t: std::marker::PhantomData, + component, + } + } +} + +// App Extension Methods +pub trait AppRegisterComponentEvents { + fn add_component_events(&mut self) -> &mut Self; +} + +impl AppRegisterComponentEvents for App { + fn add_component_events(&mut self) -> &mut Self { + self.add_event::>() + .add_event::>() + .add_event::>(); + self + } +} + +// Startup State + +#[derive(Resource)] +struct CachedInsertComponentEventsState { + event_state: SystemState>>, +} + +#[derive(Resource)] +struct CachedUpdateComponentEventsState { + event_state: SystemState>>, +} + +#[derive(Resource)] +struct CachedRemoveComponentEventsState { + event_state: SystemState>>, +} + +// this is a system +pub fn component_events_startup(world: &mut BevyWorld) { + let insert_event_state: SystemState>> = + SystemState::new(world); + world.insert_resource(CachedInsertComponentEventsState { + event_state: insert_event_state, + }); + + let update_event_state: SystemState>> = + SystemState::new(world); + world.insert_resource(CachedUpdateComponentEventsState { + event_state: update_event_state, + }); + + let remove_event_state: SystemState>> = + SystemState::new(world); + world.insert_resource(CachedRemoveComponentEventsState { + event_state: remove_event_state, + }); +} + +// this is not a system! It should be wrapped! +pub fn get_component_events( + world: &mut BevyWorld, +) -> Vec> { + let mut events_collection: Vec> = Vec::new(); + + // Insert + + world.resource_scope( + |world, mut events_reader_state: Mut>| { + let mut events_reader = events_reader_state.event_state.get_mut(world); + + for events in events_reader.read() { + let events_clone: InsertComponentEvents = Clone::clone(events); + // info!("insert_component_events() events"); + events_collection.push(ComponentEvents::Insert(events_clone)); + } + }, + ); + + // Update + + world.resource_scope( + |world, mut events_reader_state: Mut>| { + let mut events_reader = events_reader_state.event_state.get_mut(world); + + for events in events_reader.read() { + let events_clone: UpdateComponentEvents = Clone::clone(events); + + events_collection.push(ComponentEvents::Update(events_clone)); + } + }, + ); + + // Remove + + world.resource_scope( + |world, mut events_reader_state: Mut>| { + let mut events_reader = events_reader_state.event_state.get_mut(world); + + for events in events_reader.read() { + let events_clone: RemoveComponentEvents = Clone::clone(events); + events_collection.push(ComponentEvents::Remove(events_clone)); + } + }, + ); + + events_collection +} + +fn insert_component_event( + world: &mut BevyWorld, + events: &InsertComponentEvents, +) { + let mut system_state: SystemState>> = + SystemState::new(world); + let mut event_writer = system_state.get_mut(world); + + for entity in events.read::() { + event_writer.send(InsertComponentEvent::::new(entity)); + } +} + +fn update_component_event( + world: &mut BevyWorld, + events: &UpdateComponentEvents, +) { + let mut system_state: SystemState>> = + SystemState::new(world); + let mut event_writer = system_state.get_mut(world); + + for (tick, entity) in events.read::() { + event_writer.send(UpdateComponentEvent::::new(tick, entity)); + } +} + +fn remove_component_event( + world: &mut BevyWorld, + events: &RemoveComponentEvents, +) { + let mut system_state: SystemState>> = + SystemState::new(world); + let mut event_writer = system_state.get_mut(world); + + for (entity, component) in events.read::() { + event_writer.send(RemoveComponentEvent::::new(entity, component)); + } +} diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 117f90d03..600d2215f 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -12,6 +12,7 @@ pub mod events; mod client; mod commands; mod components; +pub mod component_events; mod plugin; mod systems; From 2d2346cbb84cb344ff540cca48b2db7dd4bb9eff Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 18 Jul 2024 23:06:42 -0600 Subject: [PATCH 91/99] - simplifying some Entity/Room scope logic - making it so an Entity is not despawned if it leaves a Room and rejoins it before scope evaluation --- adapters/bevy/client/src/lib.rs | 2 +- server/src/server.rs | 184 +++++++++++++++------------- server/src/user.rs | 6 +- server/src/world/entity_room_map.rs | 4 + 4 files changed, 109 insertions(+), 87 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 600d2215f..4db6a361e 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -11,8 +11,8 @@ pub mod events; mod client; mod commands; -mod components; pub mod component_events; +mod components; mod plugin; mod systems; diff --git a/server/src/server.rs b/server/src/server.rs index 37fbb9b6c..f6fcbddb2 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -1457,7 +1457,7 @@ impl Server { /// Returns an iterator of all the keys of the [`Room`]s the User belongs to pub(crate) fn user_room_keys(&self, user_key: &UserKey) -> Option> { if let Some(user) = self.users.get(user_key) { - return Some(user.room_keys()); + return Some(user.room_keys().iter()); } return None; } @@ -2186,102 +2186,120 @@ impl Server { fn update_entity_scopes>(&mut self, world: &W) { for (_, room) in self.rooms.iter_mut() { while let Some((removed_user, removed_entity)) = room.pop_entity_removal_queue() { - if let Some(user) = self.users.get(&removed_user) { - if !user.has_address() { + let Some(user) = self.users.get(&removed_user) else { + continue; + }; + if !user.has_address() { + continue; + } + let Some(connection) = self.user_connections.get_mut(&user.address()) else { + continue; + }; + + // evaluate whether the Entity really needs to be despawned! + // what if the Entity shares another Room with this User? It shouldn't be despawned! + if let Some(entity_rooms) = self.entity_room_map.entity_get_rooms(&removed_entity) { + let user_rooms = user.room_keys(); + let has_room_in_common = entity_rooms.intersection(user_rooms).next().is_some(); + if has_room_in_common { continue; } - if let Some(connection) = self.user_connections.get_mut(&user.address()) { - // TODO: evaluate whether the Entity really needs to be despawned! - // What if the Entity shares another Room with this User? It shouldn't be despawned! + } - // check if host has entity, because it may have been removed from room before despawning, and we don't want to double despawn - if connection - .base - .host_world_manager - .host_has_entity(&removed_entity) - { - //remove entity from user connection - connection - .base - .host_world_manager - .despawn_entity(&removed_entity); - } - } + + // check if host has entity, because it may have been removed from room before despawning, and we don't want to double despawn + if connection + .base + .host_world_manager + .host_has_entity(&removed_entity) + { + //remove entity from user connection + connection + .base + .host_world_manager + .despawn_entity(&removed_entity); } } + } + for (_, room) in self.rooms.iter_mut() { // TODO: we should be able to cache these tuples of keys to avoid building a new // list each time for user_key in room.user_keys() { - if let Some(user) = self.users.get(user_key) { - if !user.has_address() { + let Some(user) = self.users.get(user_key) else { + continue; + }; + if !user.has_address() { + continue; + } + let Some(connection) = self.user_connections.get_mut(&user.address()) else { + continue; + }; + for entity in room.entities() { + if !world.has_entity(entity) { + continue; + } + if self + .global_world_manager + .entity_is_public_and_owned_by_user(user_key, entity) + { + // entity is owned by client, but it is public, so we don't need to replicate it continue; } - if let Some(connection) = self.user_connections.get_mut(&user.address()) { - for entity in room.entities() { - if world.has_entity(entity) { - if self - .global_world_manager - .entity_is_public_and_owned_by_user(user_key, entity) - { - // entity is owned by client, but it is public, so we don't need to replicate it - continue; - } - let currently_in_scope = - connection.base.host_world_manager.host_has_entity(entity); - - let should_be_in_scope = if let Some(in_scope) = - self.entity_scope_map.get(user_key, entity) - { - *in_scope - } else { - false - }; - - if should_be_in_scope { - if !currently_in_scope { - let component_kinds = self - .global_world_manager - .component_kinds(entity) - .unwrap(); - // add entity & components to the connections local scope - connection.base.host_world_manager.init_entity( - &mut connection.base.local_world_manager, - entity, - component_kinds, - ); + let currently_in_scope = + connection.base.host_world_manager.host_has_entity(entity); - // if entity is delegated, send message to connection - if self.global_world_manager.entity_is_delegated(entity) { - let event_message = - EntityEventMessage::new_enable_delegation( - &self.global_world_manager, - entity, - ); - let mut converter = EntityConverterMut::new( - &self.global_world_manager, - &mut connection.base.local_world_manager, - ); - let channel_kind = ChannelKind::of::(); - let message = MessageContainer::from_write( - Box::new(event_message), - &mut converter, - ); - connection.base.message_manager.send_message( - &self.protocol.message_kinds, - &mut converter, - &channel_kind, - message, - ); - } - } - } else if currently_in_scope { - // remove entity from the connections local scope - connection.base.host_world_manager.despawn_entity(entity); - } - } + let should_be_in_scope = if let Some(in_scope) = + self.entity_scope_map.get(user_key, entity) + { + *in_scope + } else { + false + }; + + if should_be_in_scope { + if currently_in_scope { + continue; + } + let component_kinds = self + .global_world_manager + .component_kinds(entity) + .unwrap(); + // add entity & components to the connections local scope + connection.base.host_world_manager.init_entity( + &mut connection.base.local_world_manager, + entity, + component_kinds, + ); + + // if entity is delegated, send message to connection + if !self.global_world_manager.entity_is_delegated(entity) { + continue; } + let event_message = + EntityEventMessage::new_enable_delegation( + &self.global_world_manager, + entity, + ); + let mut converter = EntityConverterMut::new( + &self.global_world_manager, + &mut connection.base.local_world_manager, + ); + let channel_kind = ChannelKind::of::(); + let message = MessageContainer::from_write( + Box::new(event_message), + &mut converter, + ); + connection.base.message_manager.send_message( + &self.protocol.message_kinds, + &mut converter, + &channel_kind, + message, + ); + } else if currently_in_scope { + // remove entity from the connections local scope + connection.base.host_world_manager.despawn_entity(entity); } } } diff --git a/server/src/user.rs b/server/src/user.rs index 0dafdba69..3f08781ca 100644 --- a/server/src/user.rs +++ b/server/src/user.rs @@ -64,8 +64,8 @@ impl User { self.rooms_cache.remove(room_key); } - pub(crate) fn room_keys(&self) -> Iter { - self.rooms_cache.iter() + pub(crate) fn room_keys(&self) -> &HashSet { + &self.rooms_cache } pub(crate) fn room_count(&self) -> usize { @@ -145,7 +145,7 @@ impl<'s, E: Copy + Eq + Hash + Send + Sync> UserMut<'s, E> { } /// Returns an iterator of all the keys of the [`Room`]s the User belongs to - pub fn room_keys(&self) -> impl Iterator { + pub fn room_keys(&self) -> Iter { self.server.user_room_keys(&self.key).unwrap() } } diff --git a/server/src/world/entity_room_map.rs b/server/src/world/entity_room_map.rs index ac29ee181..29726dcc0 100644 --- a/server/src/world/entity_room_map.rs +++ b/server/src/world/entity_room_map.rs @@ -16,6 +16,10 @@ impl EntityRoomMap { } } + pub(crate) fn entity_get_rooms(&self, entity: &E) -> Option<&HashSet> { + self.map.get(entity) + } + pub(crate) fn entity_add_room(&mut self, entity: &E, room_key: &RoomKey) { if !self.map.contains_key(entity) { self.map.insert(*entity, HashSet::new()); From 5d37376684136136adb880f7c4c40d3f89c20247 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Sun, 21 Jul 2024 16:03:05 -0600 Subject: [PATCH 92/99] - 'advanced_handshaker' feature is now only used when using `transport_udp`, which makes it so User's don't have to worry about implementation details - Client now handles connect Rejection events properly --- adapters/bevy/client/Cargo.toml | 2 +- adapters/bevy/server/Cargo.toml | 2 +- adapters/bevy/shared/Cargo.toml | 4 +- client/Cargo.toml | 5 +- client/src/client.rs | 15 ++- client/src/events.rs | 8 +- client/src/handshake/mod.rs | 2 +- client/src/handshake/simple_handshaker.rs | 6 +- demos/basic/client/app/Cargo.toml | 2 +- demos/basic/server/Cargo.toml | 2 +- demos/basic/shared/Cargo.toml | 2 +- server/Cargo.toml | 5 +- server/src/handshake/advanced_handshaker.rs | 11 ++- server/src/handshake/mod.rs | 7 +- server/src/handshake/simple_handshaker.rs | 10 +- server/src/server.rs | 25 +++-- server/src/transport/mod.rs | 11 ++- server/src/transport/webrtc.rs | 27 +++-- server/src/user.rs | 26 ++++- socket/server/src/session.rs | 103 ++++++++++++-------- 20 files changed, 172 insertions(+), 103 deletions(-) diff --git a/adapters/bevy/client/Cargo.toml b/adapters/bevy/client/Cargo.toml index 95e384c99..192479c5b 100644 --- a/adapters/bevy/client/Cargo.toml +++ b/adapters/bevy/client/Cargo.toml @@ -17,7 +17,7 @@ transport_webrtc = [ "naia-client/transport_webrtc" ] transport_udp = [ "naia-client/transport_udp" ] [dependencies] -naia-client = { version = "0.22", path = "../../../client", features = ["bevy_support", "wbindgen", "advanced_handshake"] } +naia-client = { version = "0.22", path = "../../../client", features = ["bevy_support", "wbindgen"] } naia-bevy-shared = { version = "0.22", path = "../shared" } bevy_app = { version = "0.13", default-features=false } bevy_ecs = { version = "0.13", default-features=false } diff --git a/adapters/bevy/server/Cargo.toml b/adapters/bevy/server/Cargo.toml index b99638747..b9cb47a44 100644 --- a/adapters/bevy/server/Cargo.toml +++ b/adapters/bevy/server/Cargo.toml @@ -17,7 +17,7 @@ transport_webrtc = [ "naia-server/transport_webrtc" ] transport_udp = [ "naia-server/transport_udp" ] [dependencies] -naia-server = { version = "0.22", path = "../../../server", features = ["bevy_support", "advanced_handshake"] } +naia-server = { version = "0.22", path = "../../../server", features = ["bevy_support"] } naia-bevy-shared = { version = "0.22", path = "../shared" } bevy_app = { version = "0.13", default-features=false } bevy_ecs = { version = "0.13", default-features=false } diff --git a/adapters/bevy/shared/Cargo.toml b/adapters/bevy/shared/Cargo.toml index 46b1fef71..5500335ef 100644 --- a/adapters/bevy/shared/Cargo.toml +++ b/adapters/bevy/shared/Cargo.toml @@ -13,9 +13,11 @@ edition = "2021" maintenance = { status = "actively-developed" } [features] +# this should be used when the underlying transport does not handle it for you (i.e. UDP) +advanced_handshake = [ "naia-shared/advanced_handshake" ] [dependencies] -naia-shared = { version = "0.22", path = "../../../shared", features = ["bevy_support", "wbindgen", "advanced_handshake"] } +naia-shared = { version = "0.22", path = "../../../shared", features = ["bevy_support", "wbindgen"] } bevy_app = { version = "0.13", default-features=false } bevy_ecs = { version = "0.13", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/client/Cargo.toml b/client/Cargo.toml index 099260494..7d3b95769 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -22,10 +22,7 @@ mquad = [ "naia-shared/mquad", "naia-client-socket?/mquad" ] bevy_support = ["naia-shared/bevy_support"] zstd_support = ["naia-shared/zstd_support"] transport_webrtc = [ "naia-client-socket" ] -transport_udp = [ "local_ipaddress" ] - -# this should be used when the underlying transport does not handle it for you (i.e. UDP) -advanced_handshake = ["naia-shared/advanced_handshake"] +transport_udp = [ "local_ipaddress", "naia-shared/advanced_handshake" ] [dependencies] naia-shared = { version = "0.22", path = "../shared" } diff --git a/client/src/client.rs b/client/src/client.rs index f36c9589c..18e640656 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -60,7 +60,7 @@ impl Client { let compression_config = protocol.compression.clone(); - Client { + Self { // Config client_config: client_config.clone(), protocol, @@ -1111,7 +1111,7 @@ impl Client { return; } IdentityReceiverResult::ErrorResponseCode(code) => { - warn!("Authentication error status code: {}", code); + // warn!("Authentication error status code: {}", code); // reset connection self.io = Io::new( @@ -1119,9 +1119,14 @@ impl Client { &self.protocol.compression, ); - // push out error - self.incoming_events - .push_error(NaiaClientError::IdError(code)); + if code == 401 { + // push out rejection + self.incoming_events.push_rejection(); + } else { + // push out error + self.incoming_events + .push_error(NaiaClientError::IdError(code)); + } return; } diff --git a/client/src/events.rs b/client/src/events.rs index 65b2b2091..776542a1f 100644 --- a/client/src/events.rs +++ b/client/src/events.rs @@ -9,7 +9,7 @@ use crate::NaiaClientError; pub struct Events { connections: Vec, - rejections: Vec, + rejections: Vec<()>, disconnections: Vec, client_ticks: Vec, server_ticks: Vec, @@ -135,8 +135,8 @@ impl Events { self.empty = false; } - pub(crate) fn push_rejection(&mut self, socket_addr: &SocketAddr) { - self.rejections.push(*socket_addr); + pub(crate) fn push_rejection(&mut self) { + self.rejections.push(()); self.empty = false; } @@ -342,7 +342,7 @@ impl Event for ConnectEvent { // RejectEvent pub struct RejectEvent; impl Event for RejectEvent { - type Iter = IntoIter; + type Iter = IntoIter<()>; fn iter(events: &mut Events) -> Self::Iter { let list = std::mem::take(&mut events.rejections); diff --git a/client/src/handshake/mod.rs b/client/src/handshake/mod.rs index 7f338d2ef..1c73406f5 100644 --- a/client/src/handshake/mod.rs +++ b/client/src/handshake/mod.rs @@ -5,7 +5,7 @@ use naia_shared::{BitReader, BitWriter, IdentityToken, OutgoingPacket}; use crate::connection::time_manager::TimeManager; cfg_if! { - if #[cfg(feature = "advanced_handshake")] { + if #[cfg(feature = "transport_udp")] { mod advanced_handshaker; pub use advanced_handshaker::HandshakeManager; } else { diff --git a/client/src/handshake/simple_handshaker.rs b/client/src/handshake/simple_handshaker.rs index a55b7e279..5d4447afb 100644 --- a/client/src/handshake/simple_handshaker.rs +++ b/client/src/handshake/simple_handshaker.rs @@ -51,9 +51,9 @@ impl Handshaker for HandshakeManager { self.identity_token = Some(identity_token); } - fn is_connected(&self) -> bool { - self.connection_state == HandshakeState::Connected - } + // fn is_connected(&self) -> bool { + // self.connection_state == HandshakeState::Connected + // } // Give handshake manager the opportunity to send out messages to the server fn send(&mut self) -> Option { diff --git a/demos/basic/client/app/Cargo.toml b/demos/basic/client/app/Cargo.toml index 16748116b..19d84e626 100644 --- a/demos/basic/client/app/Cargo.toml +++ b/demos/basic/client/app/Cargo.toml @@ -12,7 +12,7 @@ mquad = [ "naia-client/mquad", "naia-basic-demo-shared/mquad", "miniquad" ] wbindgen = [ "naia-client/wbindgen", "naia-basic-demo-shared/wbindgen", "log" ] [dependencies] -naia-client = { path = "../../../../client", features = [ "transport_webrtc", "advanced_handshake" ] } +naia-client = { path = "../../../../client", features = [ "transport_webrtc" ] } naia-demo-world = { path = "../../../demo_utils/demo_world" } naia-basic-demo-shared = { path = "../../shared" } cfg-if = { version = "1.0" } diff --git a/demos/basic/server/Cargo.toml b/demos/basic/server/Cargo.toml index be963875f..8096a9998 100644 --- a/demos/basic/server/Cargo.toml +++ b/demos/basic/server/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT OR Apache-2.0" publish = false [dependencies] -naia-server = { path = "../../../server", features = [ "transport_webrtc", "advanced_handshake" ] } +naia-server = { path = "../../../server", features = [ "transport_webrtc" ] } naia-demo-world = { path = "../../demo_utils/demo_world" } naia-basic-demo-shared = { path = "../shared" } log = { version = "0.4" } diff --git a/demos/basic/shared/Cargo.toml b/demos/basic/shared/Cargo.toml index 6f0bd866b..6a692e57d 100644 --- a/demos/basic/shared/Cargo.toml +++ b/demos/basic/shared/Cargo.toml @@ -12,6 +12,6 @@ wbindgen = [ "naia-shared/wbindgen" ] mquad = [ "naia-shared/mquad" ] [dependencies] -naia-shared = { path = "../../../shared", features = ["advanced_handshake"] } +naia-shared = { path = "../../../shared" } cfg-if = { version = "1.0" } log = { version = "0.4" } \ No newline at end of file diff --git a/server/Cargo.toml b/server/Cargo.toml index f393dd7ce..84eac66d6 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -20,10 +20,7 @@ maintenance = { status = "actively-developed" } bevy_support = ["naia-shared/bevy_support"] zstd_support = ["naia-shared/zstd_support"] transport_webrtc = [ "naia-server-socket" ] -transport_udp = [] - -# this should be used when the underlying transport does not handle it for you (i.e. UDP) -advanced_handshake = ["naia-shared/advanced_handshake", "ring"] +transport_udp = ["naia-shared/advanced_handshake", "ring"] [dependencies] naia-shared = { version = "0.22", path = "../shared" } diff --git a/server/src/handshake/advanced_handshaker.rs b/server/src/handshake/advanced_handshaker.rs index 2b3d94bcc..ae13747d7 100644 --- a/server/src/handshake/advanced_handshaker.rs +++ b/server/src/handshake/advanced_handshaker.rs @@ -35,14 +35,17 @@ impl Handshaker for HandshakeManager { .insert(*user_key, identity_token.clone()); } - fn delete_user(&mut self, user_key: &UserKey, address: &SocketAddr) { + // address is optional because user may not have been identified yet + fn delete_user(&mut self, user_key: &UserKey, address_opt: Option) { if let Some(identity_token) = self.identity_token_map.remove(user_key) { self.authenticated_unidentified_users .remove(&identity_token); } - self.authenticated_and_identified_users.remove(address); - self.been_handshaked_users.remove(address); - self.address_to_timestamp_map.remove(address); + if let Some(address) = address_opt { + self.authenticated_and_identified_users.remove(&address); + self.been_handshaked_users.remove(&address); + self.address_to_timestamp_map.remove(&address); + } } fn maintain_handshake( diff --git a/server/src/handshake/mod.rs b/server/src/handshake/mod.rs index 95c21a7a1..59f743884 100644 --- a/server/src/handshake/mod.rs +++ b/server/src/handshake/mod.rs @@ -5,7 +5,7 @@ use naia_shared::{BitReader, IdentityToken, OutgoingPacket, SerdeErr}; use crate::UserKey; cfg_if! { - if #[cfg(feature = "advanced_handshake")] { + if #[cfg(feature = "transport_udp")] { mod cache_map; mod advanced_handshaker; @@ -18,7 +18,10 @@ cfg_if! { pub trait Handshaker: Send + Sync { fn authenticate_user(&mut self, identity_token: &IdentityToken, user_key: &UserKey); - fn delete_user(&mut self, user_key: &UserKey, address: &SocketAddr); + + // address is optional because user may not have been identified yet + fn delete_user(&mut self, user_key: &UserKey, address_opt: Option); + fn maintain_handshake( &mut self, address: &SocketAddr, diff --git a/server/src/handshake/simple_handshaker.rs b/server/src/handshake/simple_handshaker.rs index 577a2e731..96458ae16 100644 --- a/server/src/handshake/simple_handshaker.rs +++ b/server/src/handshake/simple_handshaker.rs @@ -26,12 +26,15 @@ impl Handshaker for HandshakeManager { .insert(*user_key, identity_token.clone()); } - fn delete_user(&mut self, user_key: &UserKey, address: &SocketAddr) { + // address is optional because user may not have been identified yet + fn delete_user(&mut self, user_key: &UserKey, address_opt: Option) { if let Some(identity_token) = self.identity_token_map.remove(user_key) { self.authenticated_unidentified_users .remove(&identity_token); } - self.authenticated_and_identified_users.remove(address); + if let Some(address) = address_opt { + self.authenticated_and_identified_users.remove(&address); + } } fn maintain_handshake( @@ -54,8 +57,7 @@ impl Handshaker for HandshakeManager { } // User is authenticated - self.authenticated_and_identified_users - .insert(*address, user_key); + self.authenticated_and_identified_users.insert(*address, user_key); } else { // commented out because it's pretty common to get multiple ClientIdentifyRequests which would trigger this //warn!("Server Error: User not authenticated for: {:?}, with token: {}", address, identity_token); diff --git a/server/src/server.rs b/server/src/server.rs index f6fcbddb2..3860b4d3c 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -177,7 +177,7 @@ impl Server { .expect("Auth should be set up by this point"); if auth_sender.accept(&auth_addr, &identity_token).is_err() { warn!( - "Server Error: Cannot send auth accept packet to {}", + "Server Error: Cannot send auth accept packet to {:?}", &auth_addr ); // TODO: handle destroying any threads waiting on this response @@ -188,16 +188,18 @@ impl Server { /// Rejects an incoming Client User, terminating their attempt to establish /// a connection with the Server pub fn reject_connection(&mut self, user_key: &UserKey) { - if let Some(user) = self.users.get(user_key) { - let address = user.address(); + if let Some(user) = self.users.get_mut(user_key) { + let auth_addr = user.take_auth_address(); + + // info!("rejecting authenticated user {:?}", &auth_addr); let (auth_sender, _) = self .auth_io .as_mut() .expect("Auth should be set up by this point"); - if auth_sender.reject(&address).is_err() { + if auth_sender.reject(&auth_addr).is_err() { warn!( - "Server Error: Cannot send auth reject message to {}", - &address + "Server Error: Cannot send auth reject message to {:?}", + &auth_addr ); // TODO: handle destroying any threads waiting on this response } @@ -1523,11 +1525,14 @@ impl Server { panic!("Attempting to delete non-existant user!"); }; - info!("deleting authenticated user for {}", user.address()); - self.user_connections.remove(&user.address()); + if let Some(user_addr) = user.address_opt() { + info!("deleting authenticated user for {}", user.address()); + self.user_connections.remove(&user_addr); + } + self.entity_scope_map.remove_user(user_key); - self.handshake_manager - .delete_user(user_key, &user.address()); + + self.handshake_manager.delete_user(user_key, user.address_opt()); // Clean up all user data for room_key in user.room_keys() { diff --git a/server/src/transport/mod.rs b/server/src/transport/mod.rs index 83fb39c9b..2ceaa7d24 100644 --- a/server/src/transport/mod.rs +++ b/server/src/transport/mod.rs @@ -16,9 +16,12 @@ pub use inner::{ mod inner { - use naia_shared::IdentityToken; use std::net::SocketAddr; + use naia_shared::IdentityToken; + + use crate::user::UserAuthAddr; + pub struct SendError; pub struct RecvError; @@ -70,16 +73,16 @@ mod inner { /// fn accept( &self, - address: &SocketAddr, + address: &UserAuthAddr, identity_token: &IdentityToken, ) -> Result<(), SendError>; /// - fn reject(&self, address: &SocketAddr) -> Result<(), SendError>; + fn reject(&self, address: &UserAuthAddr) -> Result<(), SendError>; } pub trait AuthReceiver: AuthReceiverClone + Send + Sync { /// - fn receive(&mut self) -> Result, RecvError>; + fn receive(&mut self) -> Result, RecvError>; } /// Used to clone Box diff --git a/server/src/transport/webrtc.rs b/server/src/transport/webrtc.rs index ee5fda8cb..ea4943019 100644 --- a/server/src/transport/webrtc.rs +++ b/server/src/transport/webrtc.rs @@ -2,12 +2,11 @@ use std::net::SocketAddr; use naia_shared::{IdentityToken, SocketConfig}; -use naia_server_socket::{ - AuthReceiver, AuthSender, PacketReceiver, PacketSender, Socket as ServerSocket, -}; +use naia_server_socket::{AuthReceiver, AuthSender, PacketReceiver, PacketSender, Socket as ServerSocket}; pub use naia_server_socket::ServerAddrs; +use crate::user::UserAuthAddr; use super::{ AuthReceiver as TransportAuthReceiver, AuthSender as TransportAuthSender, PacketReceiver as TransportReceiver, PacketSender as TransportSender, RecvError, SendError, @@ -46,23 +45,33 @@ impl TransportAuthSender for Box { /// fn accept( &self, - address: &SocketAddr, + address: &UserAuthAddr, identity_token: &IdentityToken, ) -> Result<(), SendError> { self.as_ref() - .accept(address, identity_token) + .accept(&address.addr(), identity_token) .map_err(|_| SendError) } /// - fn reject(&self, address: &SocketAddr) -> Result<(), SendError> { - self.as_ref().reject(address).map_err(|_| SendError) + fn reject(&self, address: &UserAuthAddr) -> Result<(), SendError> { + self.as_ref().reject(&address.addr()).map_err(|_| SendError) } } impl TransportAuthReceiver for Box { /// - fn receive(&mut self) -> Result, RecvError> { - self.as_mut().receive().map_err(|_| RecvError) + fn receive(&mut self) -> Result, RecvError> { + match self.as_mut().receive() { + Ok(auth_opt) => { + match auth_opt { + Some((addr, payload)) => { + return Ok(Some((UserAuthAddr::new(addr), payload))); + } + None => { return Ok(None); } + } + } + Err(_err) => { return Err(RecvError); } + } } } diff --git a/server/src/user.rs b/server/src/user.rs index 3f08781ca..8cfacc33b 100644 --- a/server/src/user.rs +++ b/server/src/user.rs @@ -22,17 +22,33 @@ impl BigMapKey for UserKey { } } +// UserAuthAddr +#[derive(Clone, Debug)] +pub struct UserAuthAddr { + addr: SocketAddr, +} + +impl UserAuthAddr { + pub fn new(addr: SocketAddr) -> Self { + Self { addr } + } + + pub fn addr(&self) -> SocketAddr { + self.addr + } +} + // User #[derive(Clone)] pub struct User { - auth_addr: Option, + auth_addr: Option, data_addr: Option, rooms_cache: HashSet, } impl User { - pub fn new(auth_addr: SocketAddr) -> User { + pub fn new(auth_addr: UserAuthAddr) -> User { Self { auth_addr: Some(auth_addr), data_addr: None, @@ -48,7 +64,11 @@ impl User { self.data_addr.unwrap() } - pub(crate) fn take_auth_address(&mut self) -> SocketAddr { + pub fn address_opt(&self) -> Option { + self.data_addr + } + + pub(crate) fn take_auth_address(&mut self) -> UserAuthAddr { self.auth_addr.take().unwrap() } diff --git a/socket/server/src/session.rs b/socket/server/src/session.rs index c4244415f..3436890a6 100644 --- a/socket/server/src/session.rs +++ b/socket/server/src/session.rs @@ -176,7 +176,7 @@ async fn serve_auth_mux_in( continue; }; - // info!("received auth answer from app, for addr: {}, answer: {}", addr, answer); + // info!("received auth answer from app, for addr: {}, answer: {:?}", addr, answer); let mut map = map.lock().await; if let Some((Some(_), _)) = map.get(&addr) { @@ -389,10 +389,16 @@ async fn serve( // info!("Sent auth bytes to server app"); // wait for response from app - if let Ok(Some(identity_token)) = to_session_auth_receiver.await { - // info!("Server app accepted auth with identity token: {}", identity_token); - identity_token_opt = Some(identity_token); - success = true; + if let Ok(identity_token_inner_opt) = to_session_auth_receiver.await { + if let Some(identity_token) = identity_token_inner_opt { + // info!("Server app accepted auth with identity token: {}", identity_token); + identity_token_opt = Some(identity_token); + success = true; + } else { + // warn!("Server app rejected auth"); + identity_token_opt = None; + success = true; + } } } } @@ -420,53 +426,70 @@ async fn serve( // info!("reading identity token"); - let identity_token = identity_token_opt.take().unwrap(); + if let Some(identity_token) = identity_token_opt.take() { - // info!("identity token: {:?}", identity_token); + // info!("identity token: {:?}", identity_token); - let mut lines = body.lines(); - let buf = RequestBuffer::new(&mut lines); + let mut lines = body.lines(); + let buf = RequestBuffer::new(&mut lines); - match session_endpoint.http_session_request(buf).await { - Ok(resp) => { - // info!("Successful WebRTC session request"); + match session_endpoint.http_session_request(buf).await { + Ok(resp) => { + // info!("Successful WebRTC session request"); - success = true; + success = true; - let (_head, body) = resp.into_parts(); + let (_head, body) = resp.into_parts(); - let body = format!( - "{{\ + let body = format!( + "{{\ \"sdp\":{body},\ \"id\":\"{identity_token}\"\ }}", - ); - - let response = Response::builder() - .header(header::CONTENT_TYPE, "application/json") - .header( - header::ACCESS_CONTROL_ALLOW_ORIGIN, - HeaderValue::from_static("*"), - ) - .body(body) - .expect("could not combine sdp response with id token"); + ); + + let response = Response::builder() + .header(header::CONTENT_TYPE, "application/json") + .header( + header::ACCESS_CONTROL_ALLOW_ORIGIN, + HeaderValue::from_static("*"), + ) + .body(body) + .expect("could not combine sdp response with id token"); + + let mut out = response_header_to_vec(&response); + out.extend_from_slice(response.body().as_bytes()); + + info!("Successful WebRTC session request from {}", remote_addr); + + stream + .write_all(&out) + .await + .expect("found an error while writing to a stream"); + } + Err(err) => { + warn!( + "Invalid WebRTC session request from {}. Error: {}", + remote_addr, err + ); + } + } + } else { + // Server rejected auth! + let response = Response::builder() + .status(401) + .body("".to_string()) + .expect("could not build 401 response"); - let mut out = response_header_to_vec(&response); - out.extend_from_slice(response.body().as_bytes()); + let mut out = response_header_to_vec(&response); + out.extend_from_slice(response.body().as_bytes()); - info!("Successful WebRTC session request from {}", remote_addr); + info!("Rejected WebRTC session request from {}", remote_addr); - stream - .write_all(&out) - .await - .expect("found an error while writing to a stream"); - } - Err(err) => { - warn!( - "Invalid WebRTC session request from {}. Error: {}", - remote_addr, err - ); - } + stream + .write_all(&out) + .await + .expect("found an error while writing to a stream"); } } } From 0cde7776f041a3949cebcae92ed17db000c4cb7c Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 22 Jul 2024 13:58:03 -0600 Subject: [PATCH 93/99] once again updating built in link conditioner configs --- socket/shared/src/link_conditioner_config.rs | 40 +++++++++++++++----- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/socket/shared/src/link_conditioner_config.rs b/socket/shared/src/link_conditioner_config.rs index 6a041d01f..c8919cf17 100644 --- a/socket/shared/src/link_conditioner_config.rs +++ b/socket/shared/src/link_conditioner_config.rs @@ -15,7 +15,7 @@ pub struct LinkConditionerConfig { impl LinkConditionerConfig { /// Creates a new LinkConditionerConfig pub fn new(incoming_latency: u32, incoming_jitter: u32, incoming_loss: f32) -> Self { - LinkConditionerConfig { + Self { incoming_latency, incoming_jitter, incoming_loss, @@ -23,19 +23,29 @@ impl LinkConditionerConfig { } pub fn perfect_condition() -> Self { - LinkConditionerConfig { + LinkConditionSelferConfig { incoming_latency: 1, incoming_jitter: 0, incoming_loss: 0.0, } } + /// Creates a new LinkConditioner that simulates a connection which is in a + /// very good condition + pub fn very_good_condition() -> Self { + Self { + incoming_latency: 12, + incoming_jitter: 3, + incoming_loss: 0.001, + } + } + /// Creates a new LinkConditioner that simulates a connection which is in a /// good condition pub fn good_condition() -> Self { - LinkConditionerConfig { + Self { incoming_latency: 40, - incoming_jitter: 6, + incoming_jitter: 10, incoming_loss: 0.002, } } @@ -43,9 +53,9 @@ impl LinkConditionerConfig { /// Creates a new LinkConditioner that simulates a connection which is in an /// average condition pub fn average_condition() -> Self { - LinkConditionerConfig { - incoming_latency: 170, - incoming_jitter: 45, + Self { + incoming_latency: 100, + incoming_jitter: 25, incoming_loss: 0.02, } } @@ -53,10 +63,20 @@ impl LinkConditionerConfig { /// Creates a new LinkConditioner that simulates a connection which is in an /// poor condition pub fn poor_condition() -> Self { - LinkConditionerConfig { - incoming_latency: 300, - incoming_jitter: 84, + Self { + incoming_latency: 200, + incoming_jitter: 50, incoming_loss: 0.04, } } + + /// Creates a new LinkConditioner that simulates a connection which is in an + /// very poor condition + pub fn very_poor_condition() -> Self { + Self { + incoming_latency: 300, + incoming_jitter: 75, + incoming_loss: 0.06, + } + } } From 175b1c878ab6c0f6d5dc9e4061fcbf608a5568f0 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Mon, 22 Jul 2024 20:29:47 -0600 Subject: [PATCH 94/99] fix typo --- socket/shared/src/link_conditioner_config.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/socket/shared/src/link_conditioner_config.rs b/socket/shared/src/link_conditioner_config.rs index c8919cf17..4950ebc4b 100644 --- a/socket/shared/src/link_conditioner_config.rs +++ b/socket/shared/src/link_conditioner_config.rs @@ -23,7 +23,7 @@ impl LinkConditionerConfig { } pub fn perfect_condition() -> Self { - LinkConditionSelferConfig { + Self { incoming_latency: 1, incoming_jitter: 0, incoming_loss: 0.0, From 6f3d6c29bd3be9da7097267b40baacca7e9c7d70 Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Thu, 25 Jul 2024 21:08:43 -0600 Subject: [PATCH 95/99] - fix CommandHistory - additional Random method - additional FileBitWriter method --- client/src/command_history.rs | 10 +++++----- shared/serde/src/file_bit_writer.rs | 5 +++++ socket/shared/src/backends/native/random.rs | 5 +++++ socket/shared/src/backends/wasm_bindgen/random.rs | 6 ++++++ 4 files changed, 21 insertions(+), 5 deletions(-) diff --git a/client/src/command_history.rs b/client/src/command_history.rs index 2edc2aec8..9cf90048b 100644 --- a/client/src/command_history.rs +++ b/client/src/command_history.rs @@ -31,19 +31,19 @@ impl CommandHistory { // this only goes forward pub fn insert(&mut self, command_tick: Tick, new_command: T) { - if let Some((last_most_recent_command_tick, _)) = self.buffer.front() { + if let Some((last_most_recent_command_tick, _)) = self.buffer.back() { if !sequence_greater_than(command_tick, *last_most_recent_command_tick) { panic!("You must always insert a more recent command into the CommandHistory than the one you last inserted."); } } // go ahead and push - self.buffer.push_front((command_tick, new_command)); + self.buffer.push_back((command_tick, new_command)); } fn remove_to_and_including(&mut self, index: Tick) { loop { - let back_index = match self.buffer.back() { + let back_index = match self.buffer.front() { Some((index, _)) => *index, None => { return; @@ -52,12 +52,12 @@ impl CommandHistory { if sequence_greater_than(back_index, index) { return; } - self.buffer.pop_back(); + self.buffer.pop_front(); } } pub fn can_insert(&self, tick: &Tick) -> bool { - if let Some((last_most_recent_command_tick, _)) = self.buffer.front() { + if let Some((last_most_recent_command_tick, _)) = self.buffer.back() { if !sequence_greater_than(*tick, *last_most_recent_command_tick) { return false; } diff --git a/shared/serde/src/file_bit_writer.rs b/shared/serde/src/file_bit_writer.rs index 7e860c121..69691ff8c 100644 --- a/shared/serde/src/file_bit_writer.rs +++ b/shared/serde/src/file_bit_writer.rs @@ -28,6 +28,11 @@ impl FileBitWriter { self.finalize(); Box::from(self.buffer) } + + pub fn to_vec(mut self) -> Vec { + self.finalize(); + self.buffer + } } impl BitWrite for FileBitWriter { diff --git a/socket/shared/src/backends/native/random.rs b/socket/shared/src/backends/native/random.rs index bd224f18b..d455361d2 100644 --- a/socket/shared/src/backends/native/random.rs +++ b/socket/shared/src/backends/native/random.rs @@ -15,6 +15,11 @@ impl Random { rand::thread_rng().gen_range(lower..upper) } + /// returns a random i32 value between an upper & lower bound + pub fn gen_range_i32(lower: i32, upper: i32) -> i32 { + rand::thread_rng().gen_range(lower..upper) + } + /// returns a random boolean value between an upper & lower bound pub fn gen_bool() -> bool { rand::thread_rng().gen_bool(0.5) diff --git a/socket/shared/src/backends/wasm_bindgen/random.rs b/socket/shared/src/backends/wasm_bindgen/random.rs index 9da861aa9..e98186bff 100644 --- a/socket/shared/src/backends/wasm_bindgen/random.rs +++ b/socket/shared/src/backends/wasm_bindgen/random.rs @@ -17,6 +17,12 @@ impl Random { rand_range + lower } + /// returns a random i32 value between an upper & lower bound + pub fn gen_range_i32(lower: i32, upper: i32) -> i32 { + let rand_range: i32 = (random() * f64::from(upper - lower)) as i32; + rand_range + lower + } + /// returns a random boolean value between an upper & lower bound pub fn gen_bool() -> bool { random() < 0.5 From 3a013d2cb4b0a8b5e8cf44a819dd1719d41cb1ef Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Fri, 26 Jul 2024 23:01:51 -0600 Subject: [PATCH 96/99] cargo fmt and exposing a couple other types --- adapters/bevy/client/src/lib.rs | 4 +-- adapters/bevy/shared/src/lib.rs | 2 +- server/src/handshake/simple_handshaker.rs | 3 +- server/src/server.rs | 38 ++++++++++------------- server/src/transport/webrtc.rs | 22 +++++++------ socket/server/src/session.rs | 4 +-- 6 files changed, 36 insertions(+), 37 deletions(-) diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 4db6a361e..2832d9450 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -1,6 +1,6 @@ pub use naia_bevy_shared::{ - sequence_greater_than, EntityAuthStatus, Random, ReceiveEvents, Replicate, ResponseSendKey, - Tick, Timer, + sequence_greater_than, wrapping_diff, EntityAuthStatus, Random, ReceiveEvents, Replicate, + ResponseSendKey, Tick, Timer, }; pub use naia_client::{ shared::{default_channels, Instant, Message, ResponseReceiveKey}, diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 113ba2386..5ab26ec4c 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -10,7 +10,7 @@ pub use naia_shared::{ RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBevy as Replicate, ReplicateBuilder, Request, Response, ResponseReceiveKey, ResponseSendKey, SerdeBevyShared as Serde, SerdeErr, SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, Timer, - UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, + UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, Instant, }; mod change_detection; diff --git a/server/src/handshake/simple_handshaker.rs b/server/src/handshake/simple_handshaker.rs index 96458ae16..afff99035 100644 --- a/server/src/handshake/simple_handshaker.rs +++ b/server/src/handshake/simple_handshaker.rs @@ -57,7 +57,8 @@ impl Handshaker for HandshakeManager { } // User is authenticated - self.authenticated_and_identified_users.insert(*address, user_key); + self.authenticated_and_identified_users + .insert(*address, user_key); } else { // commented out because it's pretty common to get multiple ClientIdentifyRequests which would trigger this //warn!("Server Error: User not authenticated for: {:?}, with token: {}", address, identity_token); diff --git a/server/src/server.rs b/server/src/server.rs index 3860b4d3c..070c2c317 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -1532,7 +1532,8 @@ impl Server { self.entity_scope_map.remove_user(user_key); - self.handshake_manager.delete_user(user_key, user.address_opt()); + self.handshake_manager + .delete_user(user_key, user.address_opt()); // Clean up all user data for room_key in user.room_keys() { @@ -2211,7 +2212,6 @@ impl Server { } } - // check if host has entity, because it may have been removed from room before despawning, and we don't want to double despawn if connection .base @@ -2255,22 +2255,19 @@ impl Server { let currently_in_scope = connection.base.host_world_manager.host_has_entity(entity); - let should_be_in_scope = if let Some(in_scope) = - self.entity_scope_map.get(user_key, entity) - { - *in_scope - } else { - false - }; + let should_be_in_scope = + if let Some(in_scope) = self.entity_scope_map.get(user_key, entity) { + *in_scope + } else { + false + }; if should_be_in_scope { if currently_in_scope { continue; } - let component_kinds = self - .global_world_manager - .component_kinds(entity) - .unwrap(); + let component_kinds = + self.global_world_manager.component_kinds(entity).unwrap(); // add entity & components to the connections local scope connection.base.host_world_manager.init_entity( &mut connection.base.local_world_manager, @@ -2282,20 +2279,17 @@ impl Server { if !self.global_world_manager.entity_is_delegated(entity) { continue; } - let event_message = - EntityEventMessage::new_enable_delegation( - &self.global_world_manager, - entity, - ); + let event_message = EntityEventMessage::new_enable_delegation( + &self.global_world_manager, + entity, + ); let mut converter = EntityConverterMut::new( &self.global_world_manager, &mut connection.base.local_world_manager, ); let channel_kind = ChannelKind::of::(); - let message = MessageContainer::from_write( - Box::new(event_message), - &mut converter, - ); + let message = + MessageContainer::from_write(Box::new(event_message), &mut converter); connection.base.message_manager.send_message( &self.protocol.message_kinds, &mut converter, diff --git a/server/src/transport/webrtc.rs b/server/src/transport/webrtc.rs index ea4943019..8cbf907ab 100644 --- a/server/src/transport/webrtc.rs +++ b/server/src/transport/webrtc.rs @@ -2,16 +2,18 @@ use std::net::SocketAddr; use naia_shared::{IdentityToken, SocketConfig}; -use naia_server_socket::{AuthReceiver, AuthSender, PacketReceiver, PacketSender, Socket as ServerSocket}; +use naia_server_socket::{ + AuthReceiver, AuthSender, PacketReceiver, PacketSender, Socket as ServerSocket, +}; pub use naia_server_socket::ServerAddrs; -use crate::user::UserAuthAddr; use super::{ AuthReceiver as TransportAuthReceiver, AuthSender as TransportAuthSender, PacketReceiver as TransportReceiver, PacketSender as TransportSender, RecvError, SendError, Socket as TransportSocket, }; +use crate::user::UserAuthAddr; pub struct Socket { server_addrs: ServerAddrs, @@ -62,15 +64,17 @@ impl TransportAuthReceiver for Box { /// fn receive(&mut self) -> Result, RecvError> { match self.as_mut().receive() { - Ok(auth_opt) => { - match auth_opt { - Some((addr, payload)) => { - return Ok(Some((UserAuthAddr::new(addr), payload))); - } - None => { return Ok(None); } + Ok(auth_opt) => match auth_opt { + Some((addr, payload)) => { + return Ok(Some((UserAuthAddr::new(addr), payload))); + } + None => { + return Ok(None); } + }, + Err(_err) => { + return Err(RecvError); } - Err(_err) => { return Err(RecvError); } } } } diff --git a/socket/server/src/session.rs b/socket/server/src/session.rs index 3436890a6..d82e44445 100644 --- a/socket/server/src/session.rs +++ b/socket/server/src/session.rs @@ -389,7 +389,8 @@ async fn serve( // info!("Sent auth bytes to server app"); // wait for response from app - if let Ok(identity_token_inner_opt) = to_session_auth_receiver.await { + if let Ok(identity_token_inner_opt) = to_session_auth_receiver.await + { if let Some(identity_token) = identity_token_inner_opt { // info!("Server app accepted auth with identity token: {}", identity_token); identity_token_opt = Some(identity_token); @@ -427,7 +428,6 @@ async fn serve( // info!("reading identity token"); if let Some(identity_token) = identity_token_opt.take() { - // info!("identity token: {:?}", identity_token); let mut lines = body.lines(); From b49f9ff634e7d73d63fef50c4e765d75be139b1d Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Wed, 14 Aug 2024 11:55:21 -0600 Subject: [PATCH 97/99] exposing GameInstant to users of client crates --- adapters/bevy/client/src/client.rs | 6 +++++- adapters/bevy/client/src/lib.rs | 2 +- adapters/bevy/shared/src/lib.rs | 2 +- client/src/client.rs | 7 +++++++ client/src/connection/time_manager.rs | 2 +- client/src/lib.rs | 2 +- 6 files changed, 16 insertions(+), 5 deletions(-) diff --git a/adapters/bevy/client/src/client.rs b/adapters/bevy/client/src/client.rs index 0b4ab7a4f..061dd164c 100644 --- a/adapters/bevy/client/src/client.rs +++ b/adapters/bevy/client/src/client.rs @@ -10,7 +10,7 @@ use naia_bevy_shared::{ GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick, }; use naia_client::{ - shared::SocketConfig, transport::Socket, Client as NaiaClient, ConnectionStatus, + shared::{GameInstant, SocketConfig}, transport::Socket, Client as NaiaClient, ConnectionStatus, NaiaClientError, }; @@ -123,6 +123,10 @@ impl<'w, T: Send + Sync + 'static> Client<'w, T> { self.client.client.server_tick() } + pub fn tick_to_instant(&self, tick: Tick) -> Option { + self.client.client.tick_to_instant(tick) + } + // Interpolation pub fn client_interpolation(&self) -> Option { diff --git a/adapters/bevy/client/src/lib.rs b/adapters/bevy/client/src/lib.rs index 2832d9450..e7cc10395 100644 --- a/adapters/bevy/client/src/lib.rs +++ b/adapters/bevy/client/src/lib.rs @@ -1,6 +1,6 @@ pub use naia_bevy_shared::{ sequence_greater_than, wrapping_diff, EntityAuthStatus, Random, ReceiveEvents, Replicate, - ResponseSendKey, Tick, Timer, + ResponseSendKey, Tick, Timer, GameInstant, }; pub use naia_client::{ shared::{default_channels, Instant, Message, ResponseReceiveKey}, diff --git a/adapters/bevy/shared/src/lib.rs b/adapters/bevy/shared/src/lib.rs index 5ab26ec4c..82848ae30 100644 --- a/adapters/bevy/shared/src/lib.rs +++ b/adapters/bevy/shared/src/lib.rs @@ -10,7 +10,7 @@ pub use naia_shared::{ RemoteEntity, ReplicaDynMut, ReplicaDynRef, ReplicateBevy as Replicate, ReplicateBuilder, Request, Response, ResponseReceiveKey, ResponseSendKey, SerdeBevyShared as Serde, SerdeErr, SerdeIntegerConversion, SignedInteger, SignedVariableInteger, Tick, TickBufferSettings, Timer, - UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, Instant, + UnsignedInteger, UnsignedVariableInteger, WorldMutType, WorldRefType, MTU_SIZE_BYTES, Instant, GameInstant, }; mod change_detection; diff --git a/client/src/client.rs b/client/src/client.rs index 18e640656..f1f0cdc96 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -752,6 +752,13 @@ impl Client { return None; } + pub fn tick_to_instant(&self, tick: Tick) -> Option { + if let Some(connection) = &self.server_connection { + return Some(connection.time_manager.tick_to_instant(tick)); + } + return None; + } + // Interpolation /// Gets the interpolation tween amount for the current frame, for use by entities on the Client Tick (i.e. predicted) diff --git a/client/src/connection/time_manager.rs b/client/src/connection/time_manager.rs index 9f3f02885..7c19ed7c6 100644 --- a/client/src/connection/time_manager.rs +++ b/client/src/connection/time_manager.rs @@ -346,7 +346,7 @@ impl TimeManager { self.pruned_rtt_avg / 2.0 } - pub(crate) fn tick_to_instant(&self, tick: Tick) -> GameInstant { + pub fn tick_to_instant(&self, tick: Tick) -> GameInstant { let tick_diff = wrapping_diff(self.server_tick, tick); let tick_diff_duration = ((tick_diff as f32) * self.server_tick_duration_avg).round() as i32; diff --git a/client/src/lib.rs b/client/src/lib.rs index 9f254f4d9..3b2d6a1bb 100644 --- a/client/src/lib.rs +++ b/client/src/lib.rs @@ -17,7 +17,7 @@ pub mod transport; pub mod shared { pub use naia_shared::{ default_channels, sequence_greater_than, GlobalRequestId, GlobalResponseId, Instant, - Message, Protocol, Random, ResponseReceiveKey, SocketConfig, Tick, + Message, Protocol, Random, ResponseReceiveKey, SocketConfig, Tick, GameInstant, }; } From c23a5430259b2c75a9ee580b2d44f7483b42f8ec Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 17 Sep 2024 16:44:44 -0600 Subject: [PATCH 98/99] update bevy naia adapters to use bevy 0.14 --- adapters/bevy/client/Cargo.toml | 4 +-- adapters/bevy/client/src/commands.rs | 4 +-- adapters/bevy/client/src/plugin.rs | 2 +- adapters/bevy/server/Cargo.toml | 4 +-- adapters/bevy/server/src/commands.rs | 7 ++--- adapters/bevy/shared/Cargo.toml | 4 +-- adapters/bevy/shared/src/change_detection.rs | 6 ++-- adapters/bevy/shared/src/component_access.rs | 6 ++-- adapters/bevy/shared/src/protocol.rs | 4 +-- adapters/bevy/shared/src/world_data.rs | 4 +-- adapters/bevy/shared/src/world_proxy.rs | 24 +++++++-------- client/src/client.rs | 14 ++------- client/src/world/entity_mut.rs | 10 +++---- client/src/world/entity_ref.rs | 6 ++-- demos/bevy/client/Cargo.toml | 2 +- demos/bevy/client/src/systems/events.rs | 18 ++++++------ demos/bevy/client/src/systems/init.rs | 18 ++++++------ demos/bevy/server/Cargo.toml | 8 ++--- demos/bevy/shared/Cargo.toml | 2 +- server/src/server.rs | 14 ++------- server/src/world/entity_mut.rs | 12 ++++---- server/src/world/entity_ref.rs | 6 ++-- shared/Cargo.toml | 2 +- shared/src/bigmap.rs | 4 +-- shared/src/lib.rs | 2 +- shared/src/world/component/replicate.rs | 16 +++------- shared/src/world/world_type.rs | 31 +++++++++----------- socket/client/Cargo.toml | 2 +- 28 files changed, 102 insertions(+), 134 deletions(-) diff --git a/adapters/bevy/client/Cargo.toml b/adapters/bevy/client/Cargo.toml index 192479c5b..303acf058 100644 --- a/adapters/bevy/client/Cargo.toml +++ b/adapters/bevy/client/Cargo.toml @@ -19,6 +19,6 @@ transport_udp = [ "naia-client/transport_udp" ] [dependencies] naia-client = { version = "0.22", path = "../../../client", features = ["bevy_support", "wbindgen"] } naia-bevy-shared = { version = "0.22", path = "../shared" } -bevy_app = { version = "0.13", default-features=false } -bevy_ecs = { version = "0.13", default-features=false } +bevy_app = { version = "0.14", default-features=false } +bevy_ecs = { version = "0.14", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/bevy/client/src/commands.rs b/adapters/bevy/client/src/commands.rs index ed770dc11..248f488d5 100644 --- a/adapters/bevy/client/src/commands.rs +++ b/adapters/bevy/client/src/commands.rs @@ -2,8 +2,8 @@ use std::marker::PhantomData; use bevy_ecs::{ entity::Entity, - system::{Command as BevyCommand, EntityCommands}, - world::{Mut, World}, + system::EntityCommands, + world::{Mut, World, Command as BevyCommand}, }; use naia_bevy_shared::{EntityAuthStatus, HostOwned, WorldMutType, WorldProxyMut}; diff --git a/adapters/bevy/client/src/plugin.rs b/adapters/bevy/client/src/plugin.rs index 0436d3bc7..00ec7ff5b 100644 --- a/adapters/bevy/client/src/plugin.rs +++ b/adapters/bevy/client/src/plugin.rs @@ -54,7 +54,7 @@ impl PluginType for Plugin { let mut world_data = config.protocol.take_world_data(); world_data.add_systems(app); - if let Some(old_world_data) = app.world.remove_resource::() { + if let Some(old_world_data) = app.world_mut().remove_resource::() { world_data.merge(old_world_data); } diff --git a/adapters/bevy/server/Cargo.toml b/adapters/bevy/server/Cargo.toml index b9cb47a44..380ff7b25 100644 --- a/adapters/bevy/server/Cargo.toml +++ b/adapters/bevy/server/Cargo.toml @@ -19,6 +19,6 @@ transport_udp = [ "naia-server/transport_udp" ] [dependencies] naia-server = { version = "0.22", path = "../../../server", features = ["bevy_support"] } naia-bevy-shared = { version = "0.22", path = "../shared" } -bevy_app = { version = "0.13", default-features=false } -bevy_ecs = { version = "0.13", default-features=false } +bevy_app = { version = "0.14", default-features=false } +bevy_ecs = { version = "0.14", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/bevy/server/src/commands.rs b/adapters/bevy/server/src/commands.rs index f636192de..35a3cb619 100644 --- a/adapters/bevy/server/src/commands.rs +++ b/adapters/bevy/server/src/commands.rs @@ -1,14 +1,13 @@ use bevy_ecs::{ entity::Entity, - system::{Command as BevyCommand, EntityCommands}, - world::{Mut, World}, + system::EntityCommands, + world::{Mut, World, Command as BevyCommand}, }; use naia_bevy_shared::{EntityAuthStatus, HostOwned, WorldProxyMut}; use naia_server::{ReplicationConfig, UserKey}; -use crate::plugin::Singleton; -use crate::{server::ServerWrapper, Server}; +use crate::{server::ServerWrapper, Server, plugin::Singleton}; // Bevy Commands Extension pub trait CommandsExt<'a> { diff --git a/adapters/bevy/shared/Cargo.toml b/adapters/bevy/shared/Cargo.toml index 5500335ef..9dc35b604 100644 --- a/adapters/bevy/shared/Cargo.toml +++ b/adapters/bevy/shared/Cargo.toml @@ -18,6 +18,6 @@ advanced_handshake = [ "naia-shared/advanced_handshake" ] [dependencies] naia-shared = { version = "0.22", path = "../../../shared", features = ["bevy_support", "wbindgen"] } -bevy_app = { version = "0.13", default-features=false } -bevy_ecs = { version = "0.13", default-features=false } +bevy_app = { version = "0.14", default-features=false } +bevy_ecs = { version = "0.14", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/bevy/shared/src/change_detection.rs b/adapters/bevy/shared/src/change_detection.rs index 9b783fcc6..fb1cdb7ab 100644 --- a/adapters/bevy/shared/src/change_detection.rs +++ b/adapters/bevy/shared/src/change_detection.rs @@ -8,7 +8,7 @@ use bevy_ecs::{ removal_detection::RemovedComponents, system::{Query, ResMut}, }; - +use bevy_ecs::component::Component; use naia_shared::{ComponentKind, Replicate}; use crate::{HostOwned, HostOwnedMap}; @@ -58,7 +58,7 @@ pub fn on_despawn( } } -pub fn on_component_added( +pub fn on_component_added( mut events: EventWriter, query: Query<(Entity, &HostOwned), Added>, ) { @@ -71,7 +71,7 @@ pub fn on_component_added( } } -pub fn on_component_removed( +pub fn on_component_removed( mut events: EventWriter, query: Query<&HostOwned>, mut removals: RemovedComponents, diff --git a/adapters/bevy/shared/src/component_access.rs b/adapters/bevy/shared/src/component_access.rs index 924560be5..3aef405ce 100644 --- a/adapters/bevy/shared/src/component_access.rs +++ b/adapters/bevy/shared/src/component_access.rs @@ -2,7 +2,7 @@ use std::{any::Any, marker::PhantomData}; use bevy_app::{App, Update}; use bevy_ecs::{entity::Entity, schedule::IntoSystemConfigs, world::World}; - +use bevy_ecs::component::Component; use naia_shared::{GlobalWorldManagerType, ReplicaDynMutWrapper, ReplicaDynRefWrapper, Replicate}; use super::{ @@ -57,7 +57,7 @@ pub struct ComponentAccessor { phantom_r: PhantomData, } -impl ComponentAccessor { +impl ComponentAccessor { fn new() -> Self { Self { phantom_r: PhantomData::, @@ -70,7 +70,7 @@ impl ComponentAccessor { } } -impl ComponentAccess for ComponentAccessor { +impl ComponentAccess for ComponentAccessor { fn add_systems(&self, app: &mut App) { app.add_systems( Update, diff --git a/adapters/bevy/shared/src/protocol.rs b/adapters/bevy/shared/src/protocol.rs index 7550b49b0..c67752964 100644 --- a/adapters/bevy/shared/src/protocol.rs +++ b/adapters/bevy/shared/src/protocol.rs @@ -1,5 +1,5 @@ use std::time::Duration; - +use bevy_ecs::component::Component; use naia_shared::{ Channel, ChannelDirection, ChannelMode, ComponentKind, CompressionConfig, LinkConditionerConfig, Message, Protocol as InnerProtocol, Replicate, Request, @@ -89,7 +89,7 @@ impl Protocol { self } - pub fn add_component(&mut self) -> &mut Self { + pub fn add_component(&mut self) -> &mut Self { self.inner.add_component::(); self.world_data .as_mut() diff --git a/adapters/bevy/shared/src/world_data.rs b/adapters/bevy/shared/src/world_data.rs index 9d6ef6d0a..5a4ec5627 100644 --- a/adapters/bevy/shared/src/world_data.rs +++ b/adapters/bevy/shared/src/world_data.rs @@ -10,7 +10,7 @@ use bevy_ecs::{ prelude::Resource, world::{FromWorld, World}, }; - +use bevy_ecs::component::Component; use naia_shared::{ComponentKind, Replicate}; use super::component_access::{ComponentAccess, ComponentAccessor}; @@ -90,7 +90,7 @@ impl WorldData { None } - pub(crate) fn put_kind(&mut self, component_kind: &ComponentKind) { + pub(crate) fn put_kind(&mut self, component_kind: &ComponentKind) { self.kind_to_accessor_map .insert(*component_kind, ComponentAccessor::::create()); } diff --git a/adapters/bevy/shared/src/world_proxy.rs b/adapters/bevy/shared/src/world_proxy.rs index cbcebb2ea..e6cc8155b 100644 --- a/adapters/bevy/shared/src/world_proxy.rs +++ b/adapters/bevy/shared/src/world_proxy.rs @@ -5,11 +5,7 @@ use bevy_ecs::{ world::{Mut, World}, }; -use naia_shared::{ - ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, - LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, - ReplicaMutWrapper, ReplicaRefWrapper, Replicate, SerdeErr, WorldMutType, WorldRefType, -}; +use naia_shared::{ComponentFieldUpdate, ComponentKind, ComponentUpdate, GlobalWorldManagerType, LocalEntityAndGlobalEntityConverter, ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, Replicate, ReplicatedComponent, SerdeErr, WorldMutType, WorldRefType}; use super::{ component_ref::{ComponentMut, ComponentRef}, @@ -61,7 +57,7 @@ impl<'w> WorldRefType for WorldRef<'w> { entities(self.world) } - fn has_component(&self, entity: &Entity) -> bool { + fn has_component(&self, entity: &Entity) -> bool { has_component::(self.world, entity) } @@ -69,7 +65,7 @@ impl<'w> WorldRefType for WorldRef<'w> { has_component_of_kind(self.world, entity, component_kind) } - fn component(&self, entity: &Entity) -> Option> { + fn component(&self, entity: &Entity) -> Option> { component(self.world, entity) } @@ -103,7 +99,7 @@ impl<'w> WorldRefType for WorldMut<'w> { entities(self.world) } - fn has_component(&self, entity: &Entity) -> bool { + fn has_component(&self, entity: &Entity) -> bool { has_component::(self.world, entity) } @@ -111,7 +107,7 @@ impl<'w> WorldRefType for WorldMut<'w> { has_component_of_kind(self.world, entity, component_kind) } - fn component(&self, entity: &Entity) -> Option> { + fn component(&self, entity: &Entity) -> Option> { component(self.world, entity) } @@ -186,7 +182,7 @@ impl<'w> WorldMutType for WorldMut<'w> { kinds } - fn component_mut(&mut self, entity: &Entity) -> Option> { + fn component_mut(&mut self, entity: &Entity) -> Option> { if let Some(bevy_mut) = self.world.get_mut::(*entity) { let wrapper = ComponentMut(bevy_mut); let component_mut = ReplicaMutWrapper::new(wrapper); @@ -272,7 +268,7 @@ impl<'w> WorldMutType for WorldMut<'w> { }); } - fn insert_component(&mut self, entity: &Entity, component_ref: R) { + fn insert_component(&mut self, entity: &Entity, component_ref: R) { // insert into ecs self.world.entity_mut(*entity).insert(component_ref); } @@ -288,7 +284,7 @@ impl<'w> WorldMutType for WorldMut<'w> { }); } - fn remove_component(&mut self, entity: &Entity) -> Option { + fn remove_component(&mut self, entity: &Entity) -> Option { return self.world.entity_mut(*entity).take::(); } @@ -412,7 +408,7 @@ fn entities(world: &World) -> Vec { world_data.entities() } -fn has_component(world: &World, entity: &Entity) -> bool { +fn has_component(world: &World, entity: &Entity) -> bool { return world.get::(*entity).is_some(); } @@ -422,7 +418,7 @@ fn has_component_of_kind(world: &World, entity: &Entity, component_kind: &Compon .contains_type_id(>::into(*component_kind)); } -fn component<'a, R: Replicate>( +fn component<'a, R: ReplicatedComponent>( world: &'a World, entity: &Entity, ) -> Option> { diff --git a/client/src/client.rs b/client/src/client.rs index f1f0cdc96..f39ebe437 100644 --- a/client/src/client.rs +++ b/client/src/client.rs @@ -2,15 +2,7 @@ use std::{any::Any, collections::VecDeque, hash::Hash, net::SocketAddr}; use log::{info, warn}; use naia_client_socket::IdentityReceiverResult; -use naia_shared::{ - BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, - EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, - EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, - GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, - PacketType, Protocol, RemoteEntity, Replicate, Request, Response, ResponseReceiveKey, - ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, - Tick, WorldMutType, WorldRefType, -}; +use naia_shared::{BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GameInstant, GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, ReplicatedComponent, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, WorldMutType, WorldRefType}; use super::{client_config::ClientConfig, error::NaiaClientError, events::Events}; use crate::{ @@ -835,7 +827,7 @@ impl Client { } /// Adds a Component to an Entity - pub(crate) fn insert_component>( + pub(crate) fn insert_component>( &mut self, world: &mut W, entity: &E, @@ -891,7 +883,7 @@ impl Client { } /// Removes a Component from an Entity - pub(crate) fn remove_component>( + pub(crate) fn remove_component>( &mut self, world: &mut W, entity: &E, diff --git a/client/src/world/entity_mut.rs b/client/src/world/entity_mut.rs index e1ae67284..808acc5fb 100644 --- a/client/src/world/entity_mut.rs +++ b/client/src/world/entity_mut.rs @@ -1,6 +1,6 @@ use std::hash::Hash; -use naia_shared::{EntityAuthStatus, ReplicaMutWrapper, Replicate, WorldMutType}; +use naia_shared::{EntityAuthStatus, ReplicaMutWrapper, ReplicatedComponent, WorldMutType}; use crate::{Client, ReplicationConfig}; @@ -30,22 +30,22 @@ impl<'s, E: Copy + Eq + Hash + Send + Sync, W: WorldMutType> EntityMut<'s, E, // Components - pub fn has_component(&self) -> bool { + pub fn has_component(&self) -> bool { self.world.has_component::(&self.entity) } - pub fn component(&mut self) -> Option> { + pub fn component(&mut self) -> Option> { self.world.component_mut::(&self.entity) } - pub fn insert_component(&mut self, component_ref: R) -> &mut Self { + pub fn insert_component(&mut self, component_ref: R) -> &mut Self { self.client .insert_component(&mut self.world, &self.entity, component_ref); self } - pub fn remove_component(&mut self) -> Option { + pub fn remove_component(&mut self) -> Option { self.client .remove_component::(&mut self.world, &self.entity) } diff --git a/client/src/world/entity_ref.rs b/client/src/world/entity_ref.rs index f7fbf68cc..93e0129af 100644 --- a/client/src/world/entity_ref.rs +++ b/client/src/world/entity_ref.rs @@ -1,6 +1,6 @@ use std::hash::Hash; -use naia_shared::{EntityAuthStatus, ReplicaRefWrapper, Replicate, WorldRefType}; +use naia_shared::{EntityAuthStatus, ReplicaRefWrapper, ReplicatedComponent, WorldRefType}; use crate::{Client, ReplicationConfig}; @@ -24,11 +24,11 @@ impl<'s, E: Copy + Eq + Hash + Send + Sync, W: WorldRefType> EntityRef<'s, E, self.entity } - pub fn has_component(&self) -> bool { + pub fn has_component(&self) -> bool { self.world.has_component::(&self.entity) } - pub fn component(&self) -> Option> { + pub fn component(&self) -> Option> { self.world.component::(&self.entity) } diff --git a/demos/bevy/client/Cargo.toml b/demos/bevy/client/Cargo.toml index 03c8eaa43..28afca3ed 100644 --- a/demos/bevy/client/Cargo.toml +++ b/demos/bevy/client/Cargo.toml @@ -22,7 +22,7 @@ crate-type = ["cdylib", "rlib"] naia-bevy-client = { path = "../../../adapters/bevy/client", features = ["transport_webrtc"] } naia-bevy-demo-shared = { path = "../shared" } -bevy = { version = "0.13", default_features = false, features = [ "bevy_asset", "bevy_winit", "bevy_core_pipeline", "bevy_render", "bevy_sprite", "x11", "webgl2"] } +bevy = { version = "0.14", default-features = false, features = [ "bevy_asset", "bevy_winit", "bevy_core_pipeline", "bevy_render", "bevy_sprite", "x11", "webgl2"] } cfg-if = { version = "1.0" } diff --git a/demos/bevy/client/src/systems/events.rs b/demos/bevy/client/src/systems/events.rs index 85a34c7d8..5ef76ac72 100644 --- a/demos/bevy/client/src/systems/events.rs +++ b/demos/bevy/client/src/systems/events.rs @@ -8,7 +8,7 @@ use bevy::{ }, sprite::MaterialMesh2dBundle, }; - +use bevy::color::LinearRgba; use naia_bevy_client::{ events::{ ClientTickEvent, ConnectEvent, DespawnEntityEvent, DisconnectEvent, InsertComponentEvents, @@ -234,14 +234,14 @@ pub fn insert_component_events( ShapeValue::Square => { let color = { match *color.value { - ColorValue::Red => BevyColor::RED, - ColorValue::Blue => BevyColor::BLUE, - ColorValue::Yellow => BevyColor::YELLOW, - ColorValue::Green => BevyColor::GREEN, - ColorValue::White => BevyColor::WHITE, - ColorValue::Purple => BevyColor::PURPLE, - ColorValue::Orange => BevyColor::ORANGE, - ColorValue::Aqua => BevyColor::AQUAMARINE, + ColorValue::Red => BevyColor::LinearRgba(LinearRgba::RED), + ColorValue::Blue => BevyColor::LinearRgba(LinearRgba::BLUE), + ColorValue::Yellow => BevyColor::LinearRgba(LinearRgba::rgb(1.0, 1.0, 0.0)), + ColorValue::Green => BevyColor::LinearRgba(LinearRgba::GREEN), + ColorValue::White => BevyColor::LinearRgba(LinearRgba::WHITE), + ColorValue::Purple => BevyColor::LinearRgba(LinearRgba::rgb(1.0, 0.0, 1.0)), + ColorValue::Orange => BevyColor::LinearRgba(LinearRgba::rgb(1.0, 0.5, 0.0)), + ColorValue::Aqua => BevyColor::LinearRgba(LinearRgba::rgb(0.0, 1.0, 1.0)), } }; diff --git a/demos/bevy/client/src/systems/init.rs b/demos/bevy/client/src/systems/init.rs index a570b14bb..d59e675c0 100644 --- a/demos/bevy/client/src/systems/init.rs +++ b/demos/bevy/client/src/systems/init.rs @@ -2,7 +2,7 @@ use bevy::{ log::info, prelude::{Assets, Camera2dBundle, Circle, Color, ColorMaterial, Commands, Mesh, ResMut}, }; - +use bevy::color::LinearRgba; use naia_bevy_client::{transport::webrtc, Client}; use naia_bevy_demo_shared::messages::Auth; @@ -27,14 +27,14 @@ pub fn init( let mut global = Global::default(); // Load colors - global.red = materials.add(ColorMaterial::from(Color::RED)); - global.blue = materials.add(ColorMaterial::from(Color::BLUE)); - global.yellow = materials.add(ColorMaterial::from(Color::YELLOW)); - global.green = materials.add(ColorMaterial::from(Color::GREEN)); - global.white = materials.add(ColorMaterial::from(Color::WHITE)); - global.purple = materials.add(ColorMaterial::from(Color::PURPLE)); - global.orange = materials.add(ColorMaterial::from(Color::ORANGE)); - global.aqua = materials.add(ColorMaterial::from(Color::AQUAMARINE)); + global.red = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::RED))); + global.blue = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::BLUE))); + global.yellow = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::rgb(1.0, 1.0, 0.0)))); + global.green = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::GREEN))); + global.white = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::WHITE))); + global.purple = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::rgb(1.0, 0.0, 1.0)))); + global.orange = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::rgb(1.0, 0.5, 0.0)))); + global.aqua = materials.add(ColorMaterial::from(Color::LinearRgba(LinearRgba::rgb(0.0, 1.0, 1.0)))); // Load shapes global.circle = meshes.add(Circle::new(6.)); diff --git a/demos/bevy/server/Cargo.toml b/demos/bevy/server/Cargo.toml index 5b7c8cb66..bbecf8c55 100644 --- a/demos/bevy/server/Cargo.toml +++ b/demos/bevy/server/Cargo.toml @@ -10,7 +10,7 @@ publish = false [dependencies] naia-bevy-demo-shared = { path = "../shared" } naia-bevy-server = { path = "../../../adapters/bevy/server", features = [ "transport_webrtc" ] } -bevy_app = { version = "0.13", default-features=false } -bevy_core = { version = "0.13", default-features=false } -bevy_ecs = { version = "0.13", default-features=false } -bevy_log = { version = "0.13", default-features=false } +bevy_app = { version = "0.14", default-features=false } +bevy_core = { version = "0.14", default-features=false } +bevy_ecs = { version = "0.14", default-features=false } +bevy_log = { version = "0.14", default-features=false } diff --git a/demos/bevy/shared/Cargo.toml b/demos/bevy/shared/Cargo.toml index 2e057cc47..c55ac6684 100644 --- a/demos/bevy/shared/Cargo.toml +++ b/demos/bevy/shared/Cargo.toml @@ -11,6 +11,6 @@ publish = false [dependencies] naia-bevy-shared = { path = "../../../adapters/bevy/shared" } -bevy_ecs = { version = "0.13", default-features=false} +bevy_ecs = { version = "0.14", default-features=false} cfg-if = { version = "1.0" } log = { version = "0.4" } \ No newline at end of file diff --git a/server/src/server.rs b/server/src/server.rs index 070c2c317..7605c9597 100644 --- a/server/src/server.rs +++ b/server/src/server.rs @@ -9,15 +9,7 @@ use std::{ use log::{info, warn}; -use naia_shared::{ - BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, - EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, - EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, - FakeEntityConverter, GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, - Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, Request, - Response, ResponseReceiveKey, ResponseSendKey, Serde, SerdeErr, SharedGlobalWorldManager, - SocketConfig, StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType, -}; +use naia_shared::{BigMap, BitReader, BitWriter, Channel, ChannelKind, ComponentKind, EntityAndGlobalEntityConverter, EntityAndLocalEntityConverter, EntityAuthStatus, EntityConverterMut, EntityDoesNotExistError, EntityEventMessage, EntityResponseEvent, FakeEntityConverter, GlobalEntity, GlobalRequestId, GlobalResponseId, GlobalWorldManagerType, Instant, Message, MessageContainer, PacketType, Protocol, RemoteEntity, Replicate, ReplicatedComponent, Request, Response, ResponseReceiveKey, ResponseSendKey, Serde, SerdeErr, SharedGlobalWorldManager, SocketConfig, StandardHeader, SystemChannel, Tick, Timer, WorldMutType, WorldRefType}; use super::{ error::NaiaServerError, @@ -1097,7 +1089,7 @@ impl Server { //// Components /// Adds a Component to an Entity - pub(crate) fn insert_component>( + pub(crate) fn insert_component>( &mut self, world: &mut W, entity: &E, @@ -1194,7 +1186,7 @@ impl Server { } /// Removes a Component from an Entity - pub(crate) fn remove_component>( + pub(crate) fn remove_component>( &mut self, world: &mut W, entity: &E, diff --git a/server/src/world/entity_mut.rs b/server/src/world/entity_mut.rs index 5dd092366..994239cff 100644 --- a/server/src/world/entity_mut.rs +++ b/server/src/world/entity_mut.rs @@ -1,6 +1,6 @@ use std::hash::Hash; -use naia_shared::{EntityAuthStatus, ReplicaMutWrapper, Replicate, WorldMutType}; +use naia_shared::{EntityAuthStatus, ReplicaMutWrapper, ReplicatedComponent, WorldMutType}; use crate::{room::RoomKey, server::Server, ReplicationConfig}; @@ -30,22 +30,22 @@ impl<'s, E: Copy + Eq + Hash + Send + Sync, W: WorldMutType> EntityMut<'s, E, // Components - pub fn has_component(&self) -> bool { + pub fn has_component(&self) -> bool { self.world.has_component::(&self.entity) } - pub fn component(&mut self) -> Option> { + pub fn component(&mut self) -> Option> { self.world.component_mut::(&self.entity) } - pub fn insert_component(&mut self, component_ref: R) -> &mut Self { + pub fn insert_component(&mut self, component_ref: R) -> &mut Self { self.server .insert_component(&mut self.world, &self.entity, component_ref); self } - pub fn insert_components(&mut self, mut component_refs: Vec) -> &mut Self { + pub fn insert_components(&mut self, mut component_refs: Vec) -> &mut Self { while let Some(component_ref) = component_refs.pop() { self.insert_component(component_ref); } @@ -53,7 +53,7 @@ impl<'s, E: Copy + Eq + Hash + Send + Sync, W: WorldMutType> EntityMut<'s, E, self } - pub fn remove_component(&mut self) -> Option { + pub fn remove_component(&mut self) -> Option { self.server .remove_component::(&mut self.world, &self.entity) } diff --git a/server/src/world/entity_ref.rs b/server/src/world/entity_ref.rs index 4f53a7c4e..6bd545268 100644 --- a/server/src/world/entity_ref.rs +++ b/server/src/world/entity_ref.rs @@ -1,6 +1,6 @@ use std::hash::Hash; -use naia_shared::{EntityAuthStatus, ReplicaRefWrapper, Replicate, WorldRefType}; +use naia_shared::{EntityAuthStatus, ReplicaRefWrapper, ReplicatedComponent, WorldRefType}; use crate::{ReplicationConfig, Server}; @@ -24,11 +24,11 @@ impl<'s, E: Copy + Eq + Hash + Send + Sync, W: WorldRefType> EntityRef<'s, E, self.entity } - pub fn has_component(&self) -> bool { + pub fn has_component(&self) -> bool { self.world.has_component::(&self.entity) } - pub fn component(&self) -> Option> { + pub fn component(&self) -> Option> { self.world.component::(&self.entity) } diff --git a/shared/Cargo.toml b/shared/Cargo.toml index 1cce43ef2..f79bbc347 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -32,5 +32,5 @@ naia-serde = { version = "0.22", path = "serde" } log = { version = "0.4" } cfg-if = { version = "1.0" } js-sys = { version = "0.3.64", optional = true } -bevy_ecs = { version = "0.13", default_features = false, optional = true } +bevy_ecs = { version = "0.14", default-features = false, optional = true } zstd = { version = "0.12.2", optional = true } \ No newline at end of file diff --git a/shared/src/bigmap.rs b/shared/src/bigmap.rs index 6faf80b8e..591c3b3b1 100644 --- a/shared/src/bigmap.rs +++ b/shared/src/bigmap.rs @@ -54,7 +54,7 @@ impl BigMap { } #[allow(clippy::type_complexity)] - pub fn iter<'a>(&'a self) -> Map, fn((&'a u64, &'a V)) -> (K, &'a V)> { + pub fn iter<'a>(&'a self) -> Map, fn((&'a u64, &'a V)) -> (K, &'a V)> { return self .inner .iter() @@ -64,7 +64,7 @@ impl BigMap { #[allow(clippy::type_complexity)] pub fn iter_mut<'a>( &'a mut self, - ) -> Map, fn((&'a u64, &'a mut V)) -> (K, &'a mut V)> { + ) -> Map, fn((&'a u64, &'a mut V)) -> (K, &'a mut V)> { return self .inner .iter_mut() diff --git a/shared/src/lib.rs b/shared/src/lib.rs index 7d29d457f..0453038b6 100644 --- a/shared/src/lib.rs +++ b/shared/src/lib.rs @@ -101,7 +101,7 @@ pub use world::{ ReplicaRefTrait, ReplicaRefWrapper, }, replicate::{ - Replicate, Replicate as ReplicateHecs, Replicate as ReplicateBevy, ReplicateBuilder, + Replicate, Replicate as ReplicateHecs, Replicate as ReplicateBevy, ReplicateBuilder, ReplicatedComponent, }, }, delegation::{ diff --git a/shared/src/world/component/replicate.rs b/shared/src/world/component/replicate.rs index 093ecdb53..bd8366899 100644 --- a/shared/src/world/component/replicate.rs +++ b/shared/src/world/component/replicate.rs @@ -44,7 +44,7 @@ pub trait ReplicateBuilder: Send + Sync + Named { /// A struct that implements Replicate is a Component, or otherwise, /// a container of Properties that can be scoped, tracked, and synced, with a /// remote host -pub trait Replicate: ReplicateInner + Named + Any { +pub trait Replicate: Sync + Send + 'static + Named + Any { /// Gets the ComponentKind of this type fn kind(&self) -> ComponentKind; fn to_any(&self) -> &dyn Any; @@ -119,20 +119,12 @@ cfg_if! { if #[cfg(feature = "bevy_support")] { // Require that Bevy Component to be implemented - use bevy_ecs::component::{TableStorage, Component}; + use bevy_ecs::component::Component; - pub trait ReplicateInner: Component + Sync + Send + 'static {} - - impl ReplicateInner for T - where T: Component + Sync + Send + 'static { - } + pub trait ReplicatedComponent: Replicate + Component {} } else { - pub trait ReplicateInner: Sync + Send + 'static {} - - impl ReplicateInner for T - where T: Sync + Send + 'static { - } + pub trait ReplicatedComponent: Replicate {} } } diff --git a/shared/src/world/world_type.rs b/shared/src/world/world_type.rs index 696610b5d..0c614b4af 100644 --- a/shared/src/world/world_type.rs +++ b/shared/src/world/world_type.rs @@ -1,19 +1,16 @@ use naia_serde::SerdeErr; -use crate::{ - world::{ - component::{ - component_kinds::ComponentKind, - component_update::{ComponentFieldUpdate, ComponentUpdate}, - replica_ref::{ - ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, - }, - replicate::Replicate, +use crate::{world::{ + component::{ + component_kinds::ComponentKind, + component_update::{ComponentFieldUpdate, ComponentUpdate}, + replica_ref::{ + ReplicaDynMutWrapper, ReplicaDynRefWrapper, ReplicaMutWrapper, ReplicaRefWrapper, }, - entity::entity_converters::LocalEntityAndGlobalEntityConverter, + replicate::Replicate, }, - GlobalWorldManagerType, -}; + entity::entity_converters::LocalEntityAndGlobalEntityConverter, +}, GlobalWorldManagerType, ReplicatedComponent}; /// Structures that implement the WorldMutType trait will be able to be loaded /// into the Server at which point the Server will use this interface to keep @@ -27,11 +24,11 @@ pub trait WorldRefType { // Components /// check whether entity contains component - fn has_component(&self, entity: &E) -> bool; + fn has_component(&self, entity: &E) -> bool; /// check whether entity contains component, dynamically fn has_component_of_kind(&self, entity: &E, component_kind: &ComponentKind) -> bool; /// gets an entity's component - fn component<'a, R: Replicate>(&'a self, entity: &E) -> Option>; + fn component<'a, R: ReplicatedComponent>(&'a self, entity: &E) -> Option>; /// gets an entity's component, dynamically fn component_of_kind<'a>( &'a self, @@ -58,7 +55,7 @@ pub trait WorldMutType: WorldRefType { /// gets all of an Entity's Components fn component_kinds(&mut self, entity: &E) -> Vec; /// gets an entity's component - fn component_mut<'a, R: Replicate>( + fn component_mut<'a, R: ReplicatedComponent>( &'a mut self, entity: &E, ) -> Option>; @@ -96,11 +93,11 @@ pub trait WorldMutType: WorldRefType { component_kind: &ComponentKind, ); /// insert a component - fn insert_component(&mut self, entity: &E, component_ref: R); + fn insert_component(&mut self, entity: &E, component_ref: R); /// insert a boxed component fn insert_boxed_component(&mut self, entity: &E, boxed_component: Box); /// remove a component - fn remove_component(&mut self, entity: &E) -> Option; + fn remove_component(&mut self, entity: &E) -> Option; /// remove a component by kind fn remove_component_of_kind( &mut self, diff --git a/socket/client/Cargo.toml b/socket/client/Cargo.toml index 78e6876cc..a29b4d5f2 100644 --- a/socket/client/Cargo.toml +++ b/socket/client/Cargo.toml @@ -35,7 +35,7 @@ miniquad = { version = "0.3", features = ["log-impl"], optional = true } base64 = { version = "0.13" } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -webrtc-unreliable-client = { path = "../../../webrtc-unreliable-client/client" } +webrtc-unreliable-client = { path = "../../../webrtc-unreliable-client/client" } # webrtc-unreliable-client = { version = "0.2" } tokio = { version = "1.15", features = ["full"] } once_cell = { version = "1.4.1" } From e084bf527413fd858090d7fdfe6733dee07d2adc Mon Sep 17 00:00:00 2001 From: Connor Carpenter Date: Tue, 17 Sep 2024 16:53:08 -0600 Subject: [PATCH 99/99] update all crates to 0.23.0 --- adapters/bevy/client/Cargo.toml | 6 +++--- adapters/bevy/server/Cargo.toml | 6 +++--- adapters/bevy/shared/Cargo.toml | 4 ++-- adapters/hecs/client/Cargo.toml | 8 ++++---- adapters/hecs/server/Cargo.toml | 8 ++++---- adapters/hecs/shared/Cargo.toml | 6 +++--- client/Cargo.toml | 6 +++--- server/Cargo.toml | 6 +++--- shared/Cargo.toml | 8 ++++---- shared/derive/Cargo.toml | 4 ++-- shared/serde/Cargo.toml | 4 ++-- shared/serde/derive/Cargo.toml | 2 +- socket/client/Cargo.toml | 6 +++--- socket/server/Cargo.toml | 4 ++-- socket/shared/Cargo.toml | 2 +- 15 files changed, 40 insertions(+), 40 deletions(-) diff --git a/adapters/bevy/client/Cargo.toml b/adapters/bevy/client/Cargo.toml index 303acf058..7c7da009c 100644 --- a/adapters/bevy/client/Cargo.toml +++ b/adapters/bevy/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-bevy-client" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../../.." description = "Library to faciliate naia_client & Bevy interop" @@ -17,8 +17,8 @@ transport_webrtc = [ "naia-client/transport_webrtc" ] transport_udp = [ "naia-client/transport_udp" ] [dependencies] -naia-client = { version = "0.22", path = "../../../client", features = ["bevy_support", "wbindgen"] } -naia-bevy-shared = { version = "0.22", path = "../shared" } +naia-client = { version = "0.23", path = "../../../client", features = ["bevy_support", "wbindgen"] } +naia-bevy-shared = { version = "0.23", path = "../shared" } bevy_app = { version = "0.14", default-features=false } bevy_ecs = { version = "0.14", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/bevy/server/Cargo.toml b/adapters/bevy/server/Cargo.toml index 380ff7b25..9455aa44a 100644 --- a/adapters/bevy/server/Cargo.toml +++ b/adapters/bevy/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-bevy-server" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../../.." description = "Library to faciliate naia_server & Bevy interop" @@ -17,8 +17,8 @@ transport_webrtc = [ "naia-server/transport_webrtc" ] transport_udp = [ "naia-server/transport_udp" ] [dependencies] -naia-server = { version = "0.22", path = "../../../server", features = ["bevy_support"] } -naia-bevy-shared = { version = "0.22", path = "../shared" } +naia-server = { version = "0.23", path = "../../../server", features = ["bevy_support"] } +naia-bevy-shared = { version = "0.23", path = "../shared" } bevy_app = { version = "0.14", default-features=false } bevy_ecs = { version = "0.14", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/bevy/shared/Cargo.toml b/adapters/bevy/shared/Cargo.toml index 9dc35b604..2c39dfd3c 100644 --- a/adapters/bevy/shared/Cargo.toml +++ b/adapters/bevy/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-bevy-shared" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../../.." description = "Library to faciliate naia & Bevy interop, functionality shared by client & server versions" @@ -17,7 +17,7 @@ maintenance = { status = "actively-developed" } advanced_handshake = [ "naia-shared/advanced_handshake" ] [dependencies] -naia-shared = { version = "0.22", path = "../../../shared", features = ["bevy_support", "wbindgen"] } +naia-shared = { version = "0.23", path = "../../../shared", features = ["bevy_support", "wbindgen"] } bevy_app = { version = "0.14", default-features=false } bevy_ecs = { version = "0.14", default-features=false } log = { version = "0.4" } \ No newline at end of file diff --git a/adapters/hecs/client/Cargo.toml b/adapters/hecs/client/Cargo.toml index e91e07eb7..ad9e1ff10 100644 --- a/adapters/hecs/client/Cargo.toml +++ b/adapters/hecs/client/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "naia-hecs-client" -# 0.22 is unpublished for now, due to lack of use of this crate, as well as plans for rapid releases - 1/9/2024 -version = "0.22.0" +# 0.23 is unpublished for now, due to lack of use of this crate, as well as plans for rapid releases - 9/17/2024 +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../../.." description = "Library to faciliate naia_client & Hecs interop" @@ -22,6 +22,6 @@ transport_webrtc = [ "naia-client/transport_webrtc" ] transport_udp = [ "naia-client/transport_udp" ] [dependencies] -naia-client = { version = "0.22", path = "../../../client" } -naia-hecs-shared = { version = "0.22", path = "../shared" } +naia-client = { version = "0.23", path = "../../../client" } +naia-hecs-shared = { version = "0.23", path = "../shared" } hecs = { version = "0.10" } \ No newline at end of file diff --git a/adapters/hecs/server/Cargo.toml b/adapters/hecs/server/Cargo.toml index 7ec197090..a1fba110a 100644 --- a/adapters/hecs/server/Cargo.toml +++ b/adapters/hecs/server/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "naia-hecs-server" -# 0.22 is unpublished for now, due to lack of use of this crate, as well as plans for rapid releases - 1/9/2024 -version = "0.22.0" +# 0.23 is unpublished for now, due to lack of use of this crate, as well as plans for rapid releases - 9/17/2024 +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../../.." description = "Library to faciliate naia_server & Hecs interop" @@ -20,6 +20,6 @@ transport_webrtc = [ "naia-server/transport_webrtc" ] transport_udp = [ "naia-server/transport_udp" ] [dependencies] -naia-server = { version = "0.22", path = "../../../server" } -naia-hecs-shared = { version = "0.22", path = "../shared" } +naia-server = { version = "0.23", path = "../../../server" } +naia-hecs-shared = { version = "0.23", path = "../shared" } hecs = { version = "0.10" } \ No newline at end of file diff --git a/adapters/hecs/shared/Cargo.toml b/adapters/hecs/shared/Cargo.toml index 1e207a137..03091461d 100644 --- a/adapters/hecs/shared/Cargo.toml +++ b/adapters/hecs/shared/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "naia-hecs-shared" -# 0.22 is unpublished for now, due to lack of use of this crate, as well as plans for rapid releases - 1/9/2024 -version = "0.22.0" +# 0.23 is unpublished for now, due to lack of use of this crate, as well as plans for rapid releases - 9/17/2024 +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../../.." description = "Library to faciliate naia & Hecs interop, functionality shared by client & server versions" @@ -20,5 +20,5 @@ wbindgen = [ "naia-shared/wbindgen" ] mquad = [ "naia-shared/mquad" ] [dependencies] -naia-shared = { version = "0.22", path = "../../../shared" } +naia-shared = { version = "0.23", path = "../../../shared" } hecs = { version = "0.10" } \ No newline at end of file diff --git a/client/Cargo.toml b/client/Cargo.toml index 7d3b95769..67af9db0e 100644 --- a/client/Cargo.toml +++ b/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-client" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = ".." description = "Provides a cross-platform client that can send/receive messages to/from a server, and has a pool of in-scope entities/components that is synced with the server." @@ -25,8 +25,8 @@ transport_webrtc = [ "naia-client-socket" ] transport_udp = [ "local_ipaddress", "naia-shared/advanced_handshake" ] [dependencies] -naia-shared = { version = "0.22", path = "../shared" } -naia-client-socket = { version = "0.22", path = "../socket/client", optional = true } +naia-shared = { version = "0.23", path = "../shared" } +naia-client-socket = { version = "0.23", path = "../socket/client", optional = true } local_ipaddress = { version = "0.1", optional = true } cfg-if = { version = "1.0" } log = { version = "0.4" } \ No newline at end of file diff --git a/server/Cargo.toml b/server/Cargo.toml index 84eac66d6..ff99b764e 100644 --- a/server/Cargo.toml +++ b/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-server" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = ".." description = "A server that uses either UDP or WebRTC communication to send/receive messages to/from connected clients, and syncs registered Entities/Components to clients to whom they are in-scope." @@ -23,8 +23,8 @@ transport_webrtc = [ "naia-server-socket" ] transport_udp = ["naia-shared/advanced_handshake", "ring"] [dependencies] -naia-shared = { version = "0.22", path = "../shared" } -naia-server-socket = { version = "0.22", path = "../socket/server", optional = true } +naia-shared = { version = "0.23", path = "../shared" } +naia-server-socket = { version = "0.23", path = "../socket/server", optional = true } cfg-if = { version = "1.0" } log = { version = "0.4" } ring = { version = "0.16.15", optional = true } diff --git a/shared/Cargo.toml b/shared/Cargo.toml index f79bbc347..1b614bb50 100644 --- a/shared/Cargo.toml +++ b/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-shared" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = ".." description = "Common functionality shared between naia-server & naia-client crates" @@ -26,9 +26,9 @@ zstd_support = [ "zstd" ] advanced_handshake = [] [dependencies] -naia-socket-shared = { version = "0.22", path = "../socket/shared" } -naia-derive = { version = "0.22", path = "derive" } -naia-serde = { version = "0.22", path = "serde" } +naia-socket-shared = { version = "0.23", path = "../socket/shared" } +naia-derive = { version = "0.23", path = "derive" } +naia-serde = { version = "0.23", path = "serde" } log = { version = "0.4" } cfg-if = { version = "1.0" } js-sys = { version = "0.3.64", optional = true } diff --git a/shared/derive/Cargo.toml b/shared/derive/Cargo.toml index e0ce70847..52d964e60 100644 --- a/shared/derive/Cargo.toml +++ b/shared/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-derive" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../.." description = "Procedural macros to simplify implementation of Naia Replicate & Protocolize traits" @@ -21,7 +21,7 @@ proc-macro = true [features] [dependencies] -naia-serde-derive = { version = "0.22", path = "../serde/derive" } +naia-serde-derive = { version = "0.23", path = "../serde/derive" } proc-macro2 = "1.0" syn = { version = "2.0.29", features = ["clone-impls"] } quote = "1.0" diff --git a/shared/serde/Cargo.toml b/shared/serde/Cargo.toml index 2fe8cde15..0afcc2e0b 100644 --- a/shared/serde/Cargo.toml +++ b/shared/serde/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-serde" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter ", "Fedor ", "makepad "] workspace = "../.." description = "Bit-level de/serialization for naia" @@ -18,6 +18,6 @@ maintenance = { status = "actively-developed" } [features] [dependencies] -naia-serde-derive = { version = "0.22", path = "derive" } +naia-serde-derive = { version = "0.23", path = "derive" } log = { version = "0.4" } cfg-if = { version = "1.0" } \ No newline at end of file diff --git a/shared/serde/derive/Cargo.toml b/shared/serde/derive/Cargo.toml index e56ed37d4..285c5eca2 100644 --- a/shared/serde/derive/Cargo.toml +++ b/shared/serde/derive/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-serde-derive" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter ", "Fedor ", "makepad "] workspace = "../../.." description = "Derive methods for naia-serde" diff --git a/socket/client/Cargo.toml b/socket/client/Cargo.toml index a29b4d5f2..17d46f114 100644 --- a/socket/client/Cargo.toml +++ b/socket/client/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-client-socket" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../.." description = "Abstraction to expose common API over a UDP socket on Linux, and a unreliable WebRTC datachannel on the browser" @@ -20,7 +20,7 @@ wbindgen = [ "naia-socket-shared/wbindgen", "wasm-bindgen", "js-sys", "web_sys", mquad = [ "naia-socket-shared/mquad", "miniquad" ] [dependencies] -naia-socket-shared = { version = "0.22", path = "../shared" } +naia-socket-shared = { version = "0.23", path = "../shared" } cfg-if = { version = "1.0" } log = { version = "0.4" } wasm-bindgen = { version = "0.2", optional = true } @@ -35,7 +35,7 @@ miniquad = { version = "0.3", features = ["log-impl"], optional = true } base64 = { version = "0.13" } [target.'cfg(not(target_arch = "wasm32"))'.dependencies] -webrtc-unreliable-client = { path = "../../../webrtc-unreliable-client/client" } # webrtc-unreliable-client = { version = "0.2" } +webrtc-unreliable-client = { version = "0.3" } tokio = { version = "1.15", features = ["full"] } once_cell = { version = "1.4.1" } diff --git a/socket/server/Cargo.toml b/socket/server/Cargo.toml index 17a7941b4..df56bba10 100755 --- a/socket/server/Cargo.toml +++ b/socket/server/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-server-socket" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../.." description = "An abstraction to provide a common API over either a UDP socket or a service that can establish WebRTC connections" @@ -16,7 +16,7 @@ edition = "2021" maintenance = { status = "actively-developed" } [dependencies] -naia-socket-shared = { version = "0.22", path = "../shared" } +naia-socket-shared = { version = "0.23", path = "../shared" } log = { version = "0.4" } futures-channel = { version = "0.3", features = ["sink"] } futures-core = { version = "0.3" } diff --git a/socket/shared/Cargo.toml b/socket/shared/Cargo.toml index 5efd4bbc0..a7217a047 100644 --- a/socket/shared/Cargo.toml +++ b/socket/shared/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "naia-socket-shared" -version = "0.22.0" +version = "0.23.0" authors = ["connorcarpenter "] workspace = "../.." description = "Common data types shared between naia-server-socket & naia-client-socket crates"