naia_shared/
protocol.rs

1use std::time::Duration;
2
3use naia_socket_shared::{LinkConditionerConfig, SocketConfig};
4
5use crate::{
6    connection::compression_config::CompressionConfig,
7    messages::{
8        channels::{
9            channel::{Channel, ChannelDirection, ChannelMode, ChannelSettings},
10            channel_kinds::ChannelKinds,
11            default_channels::DefaultChannelsPlugin,
12            system_channel::SystemChannel,
13        },
14        fragment::FragmentedMessage,
15        message::Message,
16        message_kinds::MessageKinds,
17    },
18    world::component::{component_kinds::ComponentKinds, replicate::Replicate},
19    EntityEventMessage, ReliableSettings, Request, RequestOrResponse,
20};
21
22// Protocol Plugin
23pub trait ProtocolPlugin {
24    fn build(&self, protocol: &mut Protocol);
25}
26
27// Protocol
28pub struct Protocol {
29    pub channel_kinds: ChannelKinds,
30    pub message_kinds: MessageKinds,
31    pub component_kinds: ComponentKinds,
32    /// Used to configure the underlying socket
33    pub socket: SocketConfig,
34    /// The duration between each tick
35    pub tick_interval: Duration,
36    /// Configuration used to control compression parameters
37    pub compression: Option<CompressionConfig>,
38    /// Whether or not Client Authoritative Entities will be allowed
39    pub client_authoritative_entities: bool,
40    locked: bool,
41}
42
43impl Default for Protocol {
44    fn default() -> Self {
45        let mut message_kinds = MessageKinds::new();
46        message_kinds.add_message::<FragmentedMessage>();
47        message_kinds.add_message::<RequestOrResponse>();
48        message_kinds.add_message::<EntityEventMessage>();
49
50        let mut channel_kinds = ChannelKinds::new();
51        channel_kinds.add_channel::<SystemChannel>(ChannelSettings::new(
52            ChannelMode::OrderedReliable(ReliableSettings::default()),
53            ChannelDirection::Bidirectional,
54        ));
55
56        Self {
57            channel_kinds,
58            message_kinds,
59            component_kinds: ComponentKinds::new(),
60            socket: SocketConfig::new(None, None),
61            tick_interval: Duration::from_millis(50),
62            compression: None,
63            client_authoritative_entities: false,
64            locked: false,
65        }
66    }
67}
68
69impl Protocol {
70    pub fn builder() -> Self {
71        Self::default()
72    }
73
74    pub fn add_plugin<P: ProtocolPlugin>(&mut self, plugin: P) -> &mut Self {
75        self.check_lock();
76        plugin.build(self);
77        self
78    }
79
80    pub fn link_condition(&mut self, config: LinkConditionerConfig) -> &mut Self {
81        self.check_lock();
82        self.socket.link_condition = Some(config);
83        self
84    }
85
86    pub fn rtc_endpoint(&mut self, path: String) -> &mut Self {
87        self.check_lock();
88        self.socket.rtc_endpoint_path = path;
89        self
90    }
91
92    pub fn get_rtc_endpoint(&self) -> String {
93        self.socket.rtc_endpoint_path.clone()
94    }
95
96    pub fn tick_interval(&mut self, duration: Duration) -> &mut Self {
97        self.check_lock();
98        self.tick_interval = duration;
99        self
100    }
101
102    pub fn compression(&mut self, config: CompressionConfig) -> &mut Self {
103        self.check_lock();
104        self.compression = Some(config);
105        self
106    }
107
108    pub fn enable_client_authoritative_entities(&mut self) -> &mut Self {
109        self.check_lock();
110        self.client_authoritative_entities = true;
111        self
112    }
113
114    pub fn add_default_channels(&mut self) -> &mut Self {
115        self.check_lock();
116        let plugin = DefaultChannelsPlugin;
117        plugin.build(self);
118        self
119    }
120
121    pub fn add_channel<C: Channel>(
122        &mut self,
123        direction: ChannelDirection,
124        mode: ChannelMode,
125    ) -> &mut Self {
126        self.check_lock();
127        self.channel_kinds
128            .add_channel::<C>(ChannelSettings::new(mode, direction));
129        self
130    }
131
132    pub fn add_message<M: Message>(&mut self) -> &mut Self {
133        self.check_lock();
134        self.message_kinds.add_message::<M>();
135        self
136    }
137
138    pub fn add_request<Q: Request>(&mut self) -> &mut Self {
139        self.check_lock();
140        // Requests and Responses are handled just like Messages
141        self.message_kinds.add_message::<Q>();
142        self.message_kinds.add_message::<Q::Response>();
143        self
144    }
145
146    pub fn add_component<C: Replicate>(&mut self) -> &mut Self {
147        self.check_lock();
148        self.component_kinds.add_component::<C>();
149        self
150    }
151
152    pub fn lock(&mut self) {
153        self.check_lock();
154        self.locked = true;
155    }
156
157    pub fn check_lock(&self) {
158        if self.locked {
159            panic!("Protocol already locked!");
160        }
161    }
162
163    pub fn build(&mut self) -> Self {
164        std::mem::take(self)
165    }
166}