naia_bevy_client/
client.rs

1use std::{marker::PhantomData, net::SocketAddr, time::Duration};
2
3use bevy_ecs::{
4    entity::Entity,
5    system::{ResMut, Resource, SystemParam},
6};
7
8use naia_bevy_shared::{
9    Channel, EntityAndGlobalEntityConverter, EntityAuthStatus, EntityDoesNotExistError,
10    GlobalEntity, Message, Request, Response, ResponseReceiveKey, ResponseSendKey, Tick,
11};
12use naia_client::{
13    shared::{GameInstant, SocketConfig},
14    transport::Socket,
15    Client as NaiaClient, ConnectionStatus, NaiaClientError,
16};
17
18use crate::ReplicationConfig;
19
20#[derive(Resource)]
21pub struct ClientWrapper<T: Send + Sync + 'static> {
22    pub client: NaiaClient<Entity>,
23    phantom_t: PhantomData<T>,
24}
25
26impl<T: Send + Sync + 'static> ClientWrapper<T> {
27    pub fn new(client: NaiaClient<Entity>) -> Self {
28        Self {
29            client,
30            phantom_t: PhantomData,
31        }
32    }
33}
34
35// Client
36#[derive(SystemParam)]
37pub struct Client<'w, T: Send + Sync + 'static> {
38    client: ResMut<'w, ClientWrapper<T>>,
39}
40
41impl<'w, T: Send + Sync + 'static> Client<'w, T> {
42    // Public Methods //
43
44    //// Connections ////
45
46    pub fn auth<M: Message>(&mut self, auth: M) {
47        self.client.client.auth(auth);
48    }
49
50    pub fn auth_headers(&mut self, headers: Vec<(String, String)>) {
51        self.client.client.auth_headers(headers);
52    }
53
54    pub fn connect<S: Into<Box<dyn Socket>>>(&mut self, socket: S) {
55        self.client.client.connect(socket);
56    }
57
58    pub fn disconnect(&mut self) {
59        self.client.client.disconnect();
60    }
61
62    pub fn connection_status(&self) -> ConnectionStatus {
63        self.client.client.connection_status()
64    }
65
66    pub fn server_address(&self) -> Result<SocketAddr, NaiaClientError> {
67        self.client.client.server_address()
68    }
69
70    pub fn rtt(&self) -> f32 {
71        self.client.client.rtt()
72    }
73
74    pub fn jitter(&self) -> f32 {
75        self.client.client.jitter()
76    }
77
78    // Config
79    pub fn socket_config(&self) -> &SocketConfig {
80        self.client.client.socket_config()
81    }
82
83    //// Messages ////
84    pub fn send_message<C: Channel, M: Message>(&mut self, message: &M) {
85        self.client.client.send_message::<C, M>(message);
86    }
87
88    pub fn send_tick_buffer_message<C: Channel, M: Message>(&mut self, tick: &Tick, message: &M) {
89        self.client
90            .client
91            .send_tick_buffer_message::<C, M>(tick, message);
92    }
93
94    /// Requests ///
95    pub fn send_request<C: Channel, Q: Request>(
96        &mut self,
97        request: &Q,
98    ) -> Result<ResponseReceiveKey<Q::Response>, NaiaClientError> {
99        self.client.client.send_request::<C, Q>(request)
100    }
101
102    pub fn send_response<S: Response>(
103        &mut self,
104        response_key: &ResponseSendKey<S>,
105        response: &S,
106    ) -> bool {
107        self.client.client.send_response(response_key, response)
108    }
109
110    pub fn receive_response<S: Response>(
111        &mut self,
112        response_key: &ResponseReceiveKey<S>,
113    ) -> Option<S> {
114        self.client.client.receive_response(response_key)
115    }
116
117    //// Ticks ////
118
119    pub fn client_tick(&self) -> Option<Tick> {
120        self.client.client.client_tick()
121    }
122
123    pub fn client_instant(&self) -> Option<GameInstant> {
124        self.client.client.client_instant()
125    }
126
127    pub fn server_tick(&self) -> Option<Tick> {
128        self.client.client.server_tick()
129    }
130
131    pub fn server_instant(&self) -> Option<GameInstant> {
132        self.client.client.server_instant()
133    }
134
135    pub fn tick_to_instant(&self, tick: Tick) -> Option<GameInstant> {
136        self.client.client.tick_to_instant(tick)
137    }
138
139    pub fn tick_duration(&self) -> Option<Duration> {
140        self.client.client.tick_duration()
141    }
142
143    // Interpolation
144
145    pub fn client_interpolation(&self) -> Option<f32> {
146        self.client.client.client_interpolation()
147    }
148
149    pub fn server_interpolation(&self) -> Option<f32> {
150        self.client.client.server_interpolation()
151    }
152
153    // Entity Registration
154
155    pub(crate) fn enable_replication(&mut self, entity: &Entity) {
156        self.client.client.enable_entity_replication(entity);
157    }
158
159    pub(crate) fn disable_replication(&mut self, entity: &Entity) {
160        self.client.client.disable_entity_replication(entity);
161    }
162
163    pub(crate) fn replication_config(&self, entity: &Entity) -> Option<ReplicationConfig> {
164        self.client.client.entity_replication_config(entity)
165    }
166
167    pub(crate) fn entity_request_authority(&mut self, entity: &Entity) {
168        self.client.client.entity_request_authority(entity);
169    }
170
171    pub(crate) fn entity_release_authority(&mut self, entity: &Entity) {
172        self.client.client.entity_release_authority(entity);
173    }
174
175    pub(crate) fn entity_authority_status(&self, entity: &Entity) -> Option<EntityAuthStatus> {
176        self.client.client.entity_authority_status(entity)
177    }
178}
179
180impl<'w, T: Send + Sync + 'static> EntityAndGlobalEntityConverter<Entity> for Client<'w, T> {
181    fn global_entity_to_entity(
182        &self,
183        global_entity: &GlobalEntity,
184    ) -> Result<Entity, EntityDoesNotExistError> {
185        self.client.client.global_entity_to_entity(global_entity)
186    }
187
188    fn entity_to_global_entity(
189        &self,
190        entity: &Entity,
191    ) -> Result<GlobalEntity, EntityDoesNotExistError> {
192        self.client.client.entity_to_global_entity(entity)
193    }
194}