ts3_clientquery_lib/
types.rs

1mod schandler_id {
2    use super::FromQueryString;
3    use serde_derive::Deserialize;
4
5    #[derive(Copy, Clone, Debug, Deserialize)]
6    pub struct SchandlerId {
7        #[serde(rename = "schandlerid")]
8        schandler_id: i64,
9    }
10    impl SchandlerId {
11        pub fn schandler_id(&self) -> i64 {
12            self.schandler_id
13        }
14    }
15    impl FromQueryString for SchandlerId {}
16}
17
18mod notifies {
19    use super::FromQueryString;
20    use serde_derive::Deserialize;
21
22    #[derive(Clone, Debug, Deserialize)]
23    pub struct NotifyTextMessage {
24        #[serde(rename = "targetmode", default)]
25        target_mode: i8,
26        msg: String,
27        #[serde(rename = "invokerid", default)]
28        invoker_id: i64,
29        #[serde(rename = "invokername", default)]
30        invoker_name: String,
31        #[serde(rename = "invokeruid", default)]
32        invoker_uid: String,
33    }
34
35    impl NotifyTextMessage {
36        pub fn msg(&self) -> &str {
37            &self.msg
38        }
39        pub fn invoker_name(&self) -> &str {
40            &self.invoker_name
41        }
42        pub fn target_mode(&self) -> i8 {
43            self.target_mode
44        }
45        pub fn invoker_id(&self) -> i64 {
46            self.invoker_id
47        }
48        pub fn invoker_uid(&self) -> &str {
49            &self.invoker_uid
50        }
51    }
52
53    #[derive(Copy, Clone, Debug)]
54    pub struct ClientBasicInfo {
55        channel_id: i64,
56        client_id: i64,
57    }
58
59    impl ClientBasicInfo {
60        pub fn channel_id(&self) -> i64 {
61            self.channel_id
62        }
63        pub fn client_id(&self) -> i64 {
64            self.client_id
65        }
66    }
67
68    impl From<NotifyClientMovedView> for ClientBasicInfo {
69        fn from(view: NotifyClientMovedView) -> Self {
70            Self {
71                channel_id: view.channel_id(),
72                client_id: view.client_id(),
73            }
74        }
75    }
76
77    impl From<NotifyClientEnterView> for ClientBasicInfo {
78        fn from(view: NotifyClientEnterView) -> Self {
79            Self {
80                channel_id: view.channel_id(),
81                client_id: view.client_id(),
82            }
83        }
84    }
85
86    #[derive(Clone, Debug, Deserialize)]
87    pub struct NotifyClientMovedView {
88        #[serde(rename = "ctid")]
89        channel_id: i64,
90        #[serde(rename = "reasonid", default)]
91        reason_id: i64,
92        #[serde(rename = "invokerid", default)]
93        invoker_id: i64,
94        #[serde(rename = "invokeruid", default)]
95        invoker_uid: String,
96        #[serde(rename = "invokername", default)]
97        invoker_name: String,
98        #[serde(rename = "clid", default)]
99        client_id: i64,
100    }
101
102    impl NotifyClientMovedView {
103        pub fn channel_id(&self) -> i64 {
104            self.channel_id
105        }
106        pub fn reason_id(&self) -> i64 {
107            self.reason_id
108        }
109        pub fn invoker_id(&self) -> i64 {
110            self.invoker_id
111        }
112        pub fn invoker_uid(&self) -> &str {
113            &self.invoker_uid
114        }
115        pub fn invoker_name(&self) -> &str {
116            &self.invoker_name
117        }
118        pub fn client_id(&self) -> i64 {
119            self.client_id
120        }
121    }
122
123    #[derive(Clone, Debug, Deserialize)]
124    pub struct NotifyClientEnterView {
125        #[serde(rename = "clid")]
126        client_id: i64,
127        #[serde(rename = "ctid")]
128        channel_id: i64,
129        client_nickname: String,
130        client_unique_identifier: String,
131        client_country: String,
132    }
133
134    impl NotifyClientEnterView {
135        pub fn client_id(&self) -> i64 {
136            self.client_id
137        }
138        pub fn client_nickname(&self) -> &str {
139            &self.client_nickname
140        }
141        pub fn client_country(&self) -> &str {
142            &self.client_country
143        }
144        pub fn client_unique_identifier(&self) -> &str {
145            &self.client_unique_identifier
146        }
147
148        pub fn channel_id(&self) -> i64 {
149            self.channel_id
150        }
151    }
152
153    fn default_left_reason_id() -> i64 {
154        8
155    }
156
157    #[derive(Clone, Debug, Deserialize)]
158    pub struct NotifyClientLeftView {
159        #[serde(rename = "clid")]
160        client_id: i64,
161        #[serde(rename = "reasonmsg", default)]
162        reason: String,
163        #[serde(rename = "reasonid", default = "default_left_reason_id")]
164        reason_id: i64,
165        #[serde(rename = "invokerid", default)]
166        invoker_id: i64,
167        #[serde(rename = "invokeruid", default)]
168        invoker_uid: String,
169        #[serde(rename = "invokername", default)]
170        invoker_name: String,
171    }
172
173    impl NotifyClientLeftView {
174        pub fn client_id(&self) -> i64 {
175            self.client_id
176        }
177        pub fn reason(&self) -> &str {
178            &self.reason
179        }
180        pub fn reason_id(&self) -> i64 {
181            self.reason_id
182        }
183        pub fn invoker_uid(&self) -> &str {
184            &self.invoker_uid
185        }
186        pub fn invoker_name(&self) -> &str {
187            &self.invoker_name
188        }
189        pub fn invoker_id(&self) -> i64 {
190            self.invoker_id
191        }
192    }
193
194    impl FromQueryString for NotifyClientMovedView {}
195    impl FromQueryString for NotifyClientEnterView {}
196    impl FromQueryString for NotifyClientLeftView {}
197    impl FromQueryString for NotifyTextMessage {}
198}
199
200pub mod whoami {
201    use super::FromQueryString;
202    use serde_derive::Deserialize;
203
204    #[derive(Clone, Debug, Default, Deserialize)]
205    pub struct WhoAmI {
206        client_id: i64,
207        client_database_id: i64,
208    }
209
210    impl WhoAmI {
211        pub fn client_database_id(&self) -> i64 {
212            self.client_database_id
213        }
214        pub fn client_id(&self) -> i64 {
215            self.client_id
216        }
217    }
218
219    impl FromQueryString for WhoAmI {}
220}
221
222pub mod create_channel {
223    use super::FromQueryString;
224    use serde_derive::Deserialize;
225
226    #[derive(Clone, Debug, Default, Deserialize)]
227    pub struct CreateChannel {
228        cid: i64,
229    }
230
231    impl CreateChannel {
232        pub fn cid(&self) -> i64 {
233            self.cid
234        }
235    }
236
237    impl FromQueryString for CreateChannel {}
238}
239
240pub mod channel {
241    use super::FromQueryString;
242    use serde_derive::Deserialize;
243
244    #[derive(Clone, Debug, Default, Deserialize)]
245    pub struct Channel {
246        #[serde(rename = "clid")]
247        client_id: i64,
248        pid: i64,
249        channel_order: i64,
250        channel_name: String,
251        total_clients: i64,
252        channel_needed_subscribe_power: i64,
253    }
254
255    impl Channel {
256        pub fn client_id(&self) -> i64 {
257            self.client_id
258        }
259        pub fn pid(&self) -> i64 {
260            self.pid
261        }
262        pub fn channel_order(&self) -> i64 {
263            self.channel_order
264        }
265        pub fn channel_name(&self) -> &str {
266            &self.channel_name
267        }
268        pub fn total_clients(&self) -> i64 {
269            self.total_clients
270        }
271        pub fn channel_needed_subscribe_power(&self) -> i64 {
272            self.channel_needed_subscribe_power
273        }
274    }
275
276    impl FromQueryString for Channel {}
277}
278
279// TODO: Rename this
280mod client {
281    use super::FromQueryString;
282    use serde_derive::Deserialize;
283
284    #[derive(Clone, Debug, Default, Deserialize)]
285    pub struct Client {
286        #[serde(rename = "cid")]
287        channel_id: i64,
288        #[serde(rename = "clid")]
289        client_id: i64,
290        client_database_id: i64,
291        client_type: i64,
292        client_nickname: String,
293    }
294
295    impl Client {
296        pub fn client_id(&self) -> i64 {
297            self.client_id
298        }
299        pub fn channel_id(&self) -> i64 {
300            self.channel_id
301        }
302        pub fn client_database_id(&self) -> i64 {
303            self.client_database_id
304        }
305        pub fn client_type(&self) -> i64 {
306            self.client_type
307        }
308        pub fn client_nickname(&self) -> &str {
309            &self.client_nickname
310        }
311        pub fn client_is_user(&self) -> bool {
312            self.client_type == 0
313        }
314    }
315
316    impl FromQueryString for Client {}
317
318    #[cfg(test)]
319    mod test {
320        use super::{Client, FromQueryString};
321
322        const TEST_STRING: &str = "clid=8 cid=1 client_database_id=1 client_nickname=serveradmin client_type=1 client_unique_identifier=serveradmin";
323
324        #[test]
325        fn test() {
326            let result = Client::from_query(TEST_STRING).unwrap();
327            assert_eq!(result.client_id(), 8);
328            assert_eq!(result.channel_id(), 1);
329            assert_eq!(result.client_database_id(), 1);
330            assert_eq!(result.client_nickname(), "serveradmin".to_string());
331            assert_eq!(result.client_type(), 1);
332            //assert_eq!(result.client_unique_identifier(), "serveradmin".to_string());
333            assert_eq!(result.client_unique_identifier(), "1".to_string());
334        }
335    }
336}
337
338mod client_info {
339    use super::FromQueryString;
340    use serde_derive::Deserialize;
341
342    #[derive(Clone, Debug, Default, Deserialize)]
343    pub struct ClientInfo {
344        #[serde(rename = "clid")]
345        channel_id: i64,
346        #[serde(rename = "cid")]
347        client_id: i64,
348        client_input_muted: bool,
349        client_output_muted: bool,
350        #[serde(rename = "client_outputonly_muted")]
351        client_output_only_muted: bool,
352        client_input_hardware: bool,
353        client_output_hardware: bool,
354        client_unique_identifier: String,
355        client_away: bool,
356        client_idle_time: i64,
357    }
358
359    impl ClientInfo {
360        pub fn is_client_muted(&self) -> bool {
361            self.client_away
362                || self.client_input_muted
363                || self.client_output_muted
364                || !self.client_output_hardware
365                || !self.client_input_hardware
366                || self.client_idle_time / 1000 > 300
367        }
368
369        pub fn client_unique_identifier(self) -> String {
370            self.client_unique_identifier
371        }
372        pub fn channel_id(&self) -> i64 {
373            self.channel_id
374        }
375        pub fn client_id(&self) -> i64 {
376            self.client_id
377        }
378        pub fn client_input_muted(&self) -> bool {
379            self.client_input_muted
380        }
381        pub fn client_output_muted(&self) -> bool {
382            self.client_output_muted
383        }
384        pub fn client_output_only_muted(&self) -> bool {
385            self.client_output_only_muted
386        }
387        pub fn client_input_hardware(&self) -> bool {
388            self.client_input_hardware
389        }
390        pub fn client_output_hardware(&self) -> bool {
391            self.client_output_hardware
392        }
393        pub fn client_away(&self) -> bool {
394            self.client_away
395        }
396        pub fn client_idle_time(&self) -> i64 {
397            self.client_idle_time
398        }
399    }
400
401    impl FromQueryString for ClientInfo {}
402}
403
404pub mod server_info {
405    use super::FromQueryString;
406    use serde_derive::Deserialize;
407
408    #[derive(Clone, Debug, Deserialize)]
409    pub struct ServerInfo {
410        #[serde(rename = "virtualserver_unique_identifier")]
411        virtual_server_unique_identifier: String,
412    }
413
414    impl ServerInfo {
415        pub fn virtual_server_unique_identifier(&self) -> &str {
416            &self.virtual_server_unique_identifier
417        }
418    }
419
420    impl FromQueryString for ServerInfo {}
421}
422
423pub mod client_query_result {
424
425    use super::FromQueryString;
426    use serde_derive::Deserialize;
427
428    #[derive(Clone, Debug, Deserialize)]
429    pub struct DatabaseId {
430        #[serde(rename = "cluid")]
431        client_unique_id: String,
432        #[serde(rename = "cldbid")]
433        client_database_id: i64,
434    }
435
436    impl DatabaseId {
437        pub fn client_unique_id(&self) -> &str {
438            &self.client_unique_id
439        }
440        pub fn client_database_id(&self) -> i64 {
441            self.client_database_id
442        }
443    }
444
445    impl FromQueryString for DatabaseId {}
446}
447
448pub mod ban_entry {
449    use super::FromQueryString;
450    use serde_derive::Deserialize;
451    use std::fmt::{Display, Formatter};
452
453    #[derive(Clone, Debug, Deserialize)]
454    pub struct BanEntry {
455        #[serde(rename = "banid")]
456        ban_id: i64,
457        #[serde(default)]
458        ip: String,
459        #[serde(default)]
460        reason: String,
461        #[serde(rename = "invokercldbid", default)]
462        invoker_client_database_id: i64,
463        #[serde(rename = "invokername", default)]
464        invoker_name: String,
465        #[serde(rename = "invokeruid", default)]
466        invoker_uid: String,
467        #[serde(rename = "lastnickname", default)]
468        last_nickname: String,
469    }
470
471    impl BanEntry {
472        pub fn ban_id(&self) -> i64 {
473            self.ban_id
474        }
475        pub fn ip(&self) -> &str {
476            &self.ip
477        }
478        pub fn reason(&self) -> &str {
479            &self.reason
480        }
481        pub fn invoker_client_database_id(&self) -> i64 {
482            self.invoker_client_database_id
483        }
484        pub fn invoker_name(&self) -> &str {
485            &self.invoker_name
486        }
487        pub fn invoker_uid(&self) -> &str {
488            &self.invoker_uid
489        }
490        pub fn last_nickname(&self) -> &str {
491            &self.last_nickname
492        }
493    }
494
495    impl Display for BanEntry {
496        fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
497            write!(
498                f,
499                "id: {}, reason: {}, invoker: {}, operator: {}",
500                self.ban_id(),
501                self.reason(),
502                self.invoker_uid(),
503                self.invoker_name()
504            )
505        }
506    }
507
508    #[cfg(test)]
509    mod test {
510        use super::BanEntry;
511        use crate::FromQueryString;
512
513        const TEST_STRING: &str = r#"banid=5 ip name uid=953jm1Ez3CvbAx7FKzb19zAQm48= mytsid 
514        lastnickname=باب created=1541834015 duration=0 invokername=AdminUser invokercldbid=2 
515        invokeruid=QuietTeamspeak= reason enforcements=0|banid=6 ip=1.1.1.1 
516        name uid mytsid lastnickname=باب created=1541834015 duration=0 invokername=AdminUser 
517        invokercldbid=2 invokeruid=QuietTeamspeak= reason enforcements=0|banid=12 
518        ip=114.5.1.4 name uid=+1145141919810 mytsid 
519        lastnickname=!\s\s\s\s\s\s\s\s\s\s\s\s\s\sValidname created=1549729305 duration=0 
520        invokername=AdminUser invokercldbid=2 invokeruid=QuietTeamspeak= 
521        reason=Spam enforcements=0"#;
522
523        #[test]
524        fn test() {
525            TEST_STRING
526                .split('|')
527                .map(|s| BanEntry::from_query(s))
528                .for_each(|entry| drop(entry));
529        }
530    }
531
532    impl FromQueryString for BanEntry {}
533}
534mod query_status {
535    use crate::error::{QueryError, QueryResult};
536    use serde_derive::Deserialize;
537
538    #[derive(Clone, Debug, Deserialize)]
539    pub struct QueryStatus {
540        id: i32,
541        msg: String,
542    }
543
544    impl Default for QueryStatus {
545        fn default() -> Self {
546            Self {
547                id: 0,
548                msg: "ok".to_string(),
549            }
550        }
551    }
552
553    impl QueryStatus {
554        pub fn id(&self) -> i32 {
555            self.id
556        }
557        pub fn msg(&self) -> &String {
558            &self.msg
559        }
560
561        pub fn into_err(self) -> QueryError {
562            QueryError::from(self)
563        }
564
565        pub fn into_result<T>(self, ret: T) -> QueryResult<T> {
566            if self.id == 0 {
567                return Ok(ret);
568            }
569            Err(self.into_err())
570        }
571    }
572
573    impl TryFrom<&str> for QueryStatus {
574        type Error = QueryError;
575
576        fn try_from(value: &str) -> Result<Self, Self::Error> {
577            let (_, line) = value
578                .split_once("error ")
579                .ok_or_else(|| QueryError::split_error(value))?;
580            serde_teamspeak_querystring::from_str(line)
581                .map_err(|e| QueryError::parse_error(e, line))
582        }
583    }
584}
585
586pub mod prelude {
587    pub use super::notifies::ClientBasicInfo;
588    pub use super::NotifyTextMessage;
589    pub use super::QueryStatus;
590    pub use super::{
591        BanEntry, Channel, Client, CreateChannel, DatabaseId, NotifyClientEnterView,
592        NotifyClientLeftView, NotifyClientMovedView, SchandlerId, ServerInfo, WhoAmI,
593    };
594}
595
596use crate::FromQueryString;
597pub use ban_entry::BanEntry;
598pub use channel::Channel;
599pub use client::Client;
600pub use client_info::ClientInfo;
601pub use client_query_result::DatabaseId;
602pub use create_channel::CreateChannel;
603pub use notifies::{
604    NotifyClientEnterView, NotifyClientLeftView, NotifyClientMovedView, NotifyTextMessage,
605};
606pub use query_status::QueryStatus;
607pub use schandler_id::SchandlerId;
608
609pub use server_info::ServerInfo;
610pub use whoami::WhoAmI;