1#[allow(unused_imports)]
3use crate as ts3;
4
5use crate::client::Client;
6use crate::shared::list::Comma;
7use crate::shared::{ChannelGroupId, ChannelId, ClientDatabaseId, ClientId, List, ServerGroupId};
8use crate::{Decode, DecodeError, Error, ErrorKind};
9use async_trait::async_trait;
10use tokio::task::spawn;
11
12impl Client {
13 pub(crate) fn dispatch_event(&self, buf: &[u8]) -> bool {
17 let c = self.clone();
18 let handler = c.inner.read().unwrap().handler.clone();
19
20 let (event_name, rest): (&[u8], &[u8]);
23 {
24 let vec: Vec<&[u8]> = buf.splitn(2, |c| *c == b' ').collect();
25 event_name = vec[0];
26 rest = vec[1];
27 }
28
29 let buf = rest.to_owned();
31
32 match event_name {
33 b"notifycliententerview" => {
34 let event = match ClientEnterView::decode(&buf) {
35 Ok(event) => event,
36 Err(err) => {
37 handler.error(c, err);
38 return true;
39 }
40 };
41
42 spawn(async move { handler.cliententerview(c, event).await });
43 }
44 b"notifyclientleftview" => {
45 let event = match ClientLeftView::decode(&buf) {
46 Ok(event) => event,
47 Err(err) => {
48 handler.error(c, err);
49 return true;
50 }
51 };
52
53 spawn(async move { handler.clientleftview(c, event).await });
54 }
55 b"notifyserveredited" => {
56 let event = match ServerEdited::decode(&buf) {
57 Ok(event) => event,
58 Err(err) => {
59 handler.error(c, err);
60 return true;
61 }
62 };
63
64 spawn(async move { handler.serveredited(c, event).await });
65 }
66 b"notifychanneldescriptionchanged" => {
67 let event = match ChannelDescriptionChanged::decode(&buf) {
68 Ok(event) => event,
69 Err(err) => {
70 handler.error(c, err);
71 return true;
72 }
73 };
74
75 spawn(async move { handler.channeldescriptionchanged(c, event).await });
76 }
77 b"notifychannelpasswordchanged" => {
78 let event = match ChannelPasswordChanged::decode(&buf) {
79 Ok(event) => event,
80 Err(err) => {
81 handler.error(c, err);
82 return true;
83 }
84 };
85
86 spawn(async move { handler.channelpasswordchanged(c, event).await });
87 }
88 b"notifychannelmoved" => {
89 let event = match ChannelMoved::decode(&buf) {
90 Ok(event) => event,
91 Err(err) => {
92 handler.error(c, err);
93 return true;
94 }
95 };
96
97 spawn(async move { handler.channelmoved(c, event).await });
98 }
99 b"notifychanneledited" => {
100 let event = match ChannelEdited::decode(&buf) {
101 Ok(event) => event,
102 Err(err) => {
103 handler.error(c, err);
104 return true;
105 }
106 };
107
108 spawn(async move { handler.channeledited(c, event).await });
109 }
110 b"notifychannelcreated" => {
111 let event = match ChannelCreated::decode(&buf) {
112 Ok(event) => event,
113 Err(err) => {
114 handler.error(c, err);
115 return true;
116 }
117 };
118
119 spawn(async move { handler.channelcreated(c, event).await });
120 }
121 b"notifychanneldeleted" => {
122 let event = match ChannelDeleted::decode(&buf) {
123 Ok(event) => event,
124 Err(err) => {
125 handler.error(c, err);
126 return true;
127 }
128 };
129
130 spawn(async move { handler.channeldeleted(c, event).await });
131 }
132 b"notifyclientmoved" => {
133 let event = match ClientMoved::decode(&buf) {
134 Ok(event) => event,
135 Err(err) => {
136 handler.error(c, err);
137 return true;
138 }
139 };
140
141 spawn(async move { handler.clientmoved(c, event).await });
142 }
143 b"notifytextmessage" => {
144 let event = match TextMessage::decode(&buf) {
145 Ok(event) => event,
146 Err(err) => {
147 handler.error(c, err);
148 return true;
149 }
150 };
151
152 spawn(async move { handler.textmessage(c, event).await });
153 }
154 b"notifytokenused" => {
155 let event = match TokenUsed::decode(&buf) {
156 Ok(event) => event,
157 Err(err) => {
158 handler.error(c, err);
159 return true;
160 }
161 };
162
163 spawn(async move { handler.tokenused(c, event).await });
164 }
165 _ => return false,
166 }
167
168 true
169 }
170}
171
172#[async_trait]
175pub trait EventHandler: Send + Sync {
176 async fn cliententerview(&self, _client: Client, _event: ClientEnterView) {}
177 async fn clientleftview(&self, _client: Client, _event: ClientLeftView) {}
178 async fn serveredited(&self, _client: Client, _event: ServerEdited) {}
179 async fn channeldescriptionchanged(&self, _client: Client, _event: ChannelDescriptionChanged) {}
180 async fn channelpasswordchanged(&self, _client: Client, _event: ChannelPasswordChanged) {}
181 async fn channelmoved(&self, _client: Client, _event: ChannelMoved) {}
182 async fn channeledited(&self, _client: Client, _event: ChannelEdited) {}
183 async fn channelcreated(&self, _client: Client, _event: ChannelCreated) {}
184 async fn channeldeleted(&self, _client: Client, _event: ChannelDeleted) {}
185 async fn clientmoved(&self, _client: Client, _event: ClientMoved) {}
186 async fn textmessage(&self, _client: Client, _event: TextMessage) {}
187 async fn tokenused(&self, _client: Client, _event: TokenUsed) {}
188
189 fn error(&self, _client: Client, error: Error) {
190 println!("connection error: {}", error);
191 }
192}
193
194#[derive(Debug)]
196pub enum ReasonId {
197 SwitchChannel = 0,
199 Moved,
201 Timeout,
203 ChannelKick,
205 ServerKick,
207 Ban,
209 ServerLeave,
211 Edited,
213 ServerShutdown,
215}
216
217impl Decode for ReasonId {
218 type Error = Error;
219
220 fn decode(buf: &[u8]) -> Result<ReasonId, Self::Error> {
221 match u8::decode(buf)? {
222 0 => Ok(Self::SwitchChannel),
223 1 => Ok(Self::Moved),
224 2 => Ok(Self::Timeout),
225 3 => Ok(Self::ChannelKick),
226 4 => Ok(Self::ServerKick),
227 5 => Ok(Self::Ban),
228 6 => Ok(Self::ServerLeave),
229 7 => Ok(Self::Edited),
230 8 => Ok(Self::ServerShutdown),
231 b => Err(Error(ErrorKind::Decode(DecodeError::InvalidReasonId(b)))),
232 }
233 }
234}
235
236impl Default for ReasonId {
237 fn default() -> ReasonId {
238 ReasonId::SwitchChannel
239 }
240}
241
242#[derive(Debug, Decode, Default)]
244pub struct ClientEnterView {
245 pub cfid: ChannelId,
246 pub ctid: ChannelId,
247 pub reasonid: ReasonId,
248 pub clid: ClientId,
249 pub client_unique_identifier: String,
250 pub client_nickname: String,
251 pub client_input_muted: bool,
252 pub client_output_muted: bool,
253 pub client_outputonly_muted: bool,
254 pub client_input_hardware: u64,
255 pub client_output_hardware: u64,
256 pub client_is_recording: bool,
258 pub client_database_id: ClientDatabaseId,
259 pub client_channel_group_id: ChannelGroupId,
260 pub client_servergroups: List<ServerGroupId, Comma>,
261 pub client_away: bool,
262 pub client_away_message: String,
263 pub client_type: u8,
264 pub client_talk_power: u64,
266 pub client_talk_request: bool,
267 pub client_talk_request_msg: String,
268 pub client_description: String,
269 pub client_is_talker: bool,
270 pub client_nickname_phoentic: String,
271 pub client_needed_serverquey_view_power: u64,
272 pub client_icon_id: u64,
273 pub client_country: String,
274 pub client_channel_group_inherited_channel_id: u64,
275 pub client_badges: String,
276}
277
278#[derive(Debug, Decode, Default)]
280pub struct ClientLeftView {
281 pub cfid: ChannelId,
282 pub ctid: ChannelId,
283 pub reasonid: ReasonId,
284 pub invokerid: ClientId,
285 pub invokername: String,
286 pub invokeruid: String,
287 pub reasonmsg: String,
288 pub bantime: u64,
289 pub clid: ClientId,
290}
291
292#[derive(Debug, Decode, Default)]
294pub struct ServerEdited {
295 pub reasonid: ReasonId,
296 pub invokerid: ClientId,
297 pub invokername: String,
298 pub invokeruid: String,
299 pub virtualserver_name: String,
300 pub virtualserver_codec_encryption_mode: String,
301 pub virtualserver_default_server_group: ServerGroupId,
302 pub virtualserver_default_channel_group: ChannelGroupId,
303 pub virtualserver_hostbanner_url: String,
304 pub virtualserver_hostbanner_gfx_url: String,
305 pub virtualserver_hostbanner_gfx_interval: u64,
306 pub virtualserver_priority_speaker_dimm_modificator: String,
307 pub virtualserver_hostbutton_tooltip: String,
308 pub virtualserver_hostbutton_url: String,
309 pub virtualserver_hostbutton_gfx_url: String,
310 pub virtualserver_name_phoentic: String,
311 pub virtualserver_icon_id: u64,
312 pub virtualserver_hostbanner_mode: String,
313 pub virtualserver_channel_temp_delete_delay_default: u64,
314}
315
316#[derive(Debug, Decode, Default)]
318pub struct ChannelDescriptionChanged {
319 pub cid: ChannelId,
320}
321
322#[derive(Debug, Decode, Default)]
324pub struct ChannelPasswordChanged {
325 pub cid: ChannelId,
326}
327
328#[derive(Debug, Decode, Default)]
330pub struct ChannelMoved {
331 pub cid: ChannelId,
332 pub cpid: ChannelId,
333 pub order: u64,
334 pub reasonid: ReasonId,
335 pub invokerid: ClientId,
336 pub invokername: String,
337 pub invokeruid: String,
338}
339
340#[derive(Debug, Decode, Default)]
345pub struct ChannelEdited {
346 pub cid: ChannelId,
347 pub reasonid: ReasonId,
348 pub invokerid: ClientId,
349 pub invokername: String,
350 pub invokeruid: String,
351 pub channel_name: String,
352 pub channel_topic: String,
353 pub channel_codec: u8,
355 pub channel_codec_quality: u8,
356 pub channel_maxclients: u16,
357 pub channel_maxfamilyclients: u16,
358 pub channel_order: u64,
359 pub channel_flag_permanent: bool,
360 pub channel_flag_semi_permanent: bool,
361 pub channel_flag_default: bool,
362 pub channel_flag_password: String,
363 pub channel_codec_latency_factor: u64,
364 pub channel_codec_is_unencrypted: bool,
365 pub channel_delete_delay: u32,
366 pub channel_flag_maxclients_unlimited: bool,
367 pub channel_flag_maxfamilyclients_unlimited: bool,
368 pub channel_flag_maxfamilyclients_inherited: bool,
369 pub channel_needed_talk_power: u32,
370 pub channel_name_phonetic: String,
371 pub channel_icon_id: u64,
372}
373
374#[derive(Debug, Decode, Default)]
376pub struct ChannelCreated {
377 pub cid: ChannelId,
378 pub cpid: ChannelId,
379 pub channel_name: String,
380 pub channel_topic: String,
381 pub channel_codec: u8,
383 pub channel_codec_quality: u8,
384 pub channel_maxclients: u16,
385 pub channel_maxfamilyclients: u16,
386 pub channel_order: u64,
387 pub channel_flag_permanent: bool,
388 pub channel_flag_semi_permanent: bool,
389 pub channel_flag_default: bool,
390 pub channel_flag_password: bool,
391 pub channel_codec_latency_factor: u64,
392 pub channel_codec_is_unencrypted: bool,
393 pub channel_delete_delay: u32,
394 pub channel_flag_maxclients_unlimited: bool,
395 pub channel_flag_maxfamilyclients_unlimited: bool,
396 pub channel_flag_maxfamilyclients_inherited: bool,
397 pub channel_needed_talk_power: u32,
398 pub channel_name_phonetic: String,
399 pub channel_icon_id: u64,
400 pub invokerid: ClientId,
401 pub invokername: String,
402 pub invokeruid: String,
403}
404
405#[derive(Debug, Decode, Default)]
407pub struct ChannelDeleted {
408 pub invokerid: ClientId,
410 pub invokername: String,
412 pub invokeruid: String,
414 pub cid: ChannelId,
415}
416
417#[derive(Debug, Decode, Default)]
419pub struct ClientMoved {
420 pub ctid: ChannelId,
421 pub reasonid: ReasonId,
422 pub invokerid: ClientId,
423 pub invokername: String,
424 pub invokeruid: String,
425 pub clid: ChannelId,
426}
427
428#[derive(Debug, Decode, Default)]
430pub struct TextMessage {
431 pub targetmode: u64,
432 pub msg: String,
433 pub target: ClientId,
434 pub invokerid: ClientId,
435 pub invokername: String,
436 pub invokeruid: String,
437}
438
439#[derive(Debug, Decode, Default)]
441pub struct TokenUsed {
442 pub clid: ClientId,
443 pub cldbid: ClientDatabaseId,
444 pub cluid: String,
445 pub token: String,
446 pub tokencustomset: String,
447 pub token1: u64,
449 pub token2: u64,
451}
452
453pub(crate) struct Handler;
456
457impl EventHandler for Handler {}