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
22pub trait ProtocolPlugin {
24 fn build(&self, protocol: &mut Protocol);
25}
26
27pub struct Protocol {
29 pub channel_kinds: ChannelKinds,
30 pub message_kinds: MessageKinds,
31 pub component_kinds: ComponentKinds,
32 pub socket: SocketConfig,
34 pub tick_interval: Duration,
36 pub compression: Option<CompressionConfig>,
38 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 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}