#[allow(unused_imports)]
use crate as ts3;
use crate::client::Client;
use crate::{Decode, ParseError};
use async_trait::async_trait;
use std::str::FromStr;
use tokio::task;
impl Client {
pub(crate) fn dispatch_event(&self, buf: &[u8]) -> bool {
let c = self.clone();
let handler = c.inner.read().unwrap().handler.clone();
let (event_name, rest): (&[u8], &[u8]);
{
let vec: Vec<&[u8]> = buf.splitn(2, |c| *c == b' ').collect();
event_name = vec[0];
rest = vec[1];
}
let buf = rest.to_owned();
match event_name {
b"notifycliententerview" => {
task::spawn(async move {
handler
.cliententerview(c, ClientEnterView::decode(&buf).unwrap())
.await;
});
true
}
b"notifyclientleftview" => {
task::spawn(async move {
handler
.clientleftview(c, ClientLeftView::decode(&buf).unwrap())
.await;
});
true
}
b"notifyserveredited" => {
task::spawn(async move {
handler
.serveredited(c, ServerEdited::decode(&buf).unwrap())
.await;
});
true
}
b"notifychanneldescriptionchanged" => {
task::spawn(async move {
handler
.channeldescriptionchanged(c, ChannelDescriptionChanged::decode(&buf).unwrap())
.await;
});
true
}
b"notifychannelpasswordchanged" => {
task::spawn(async move {
handler
.channelpasswordchanged(c, ChannelPasswordChanged::decode(&buf).unwrap())
.await;
});
true
}
b"notifychannelmoved" => {
task::spawn(async move {
handler
.channelmoved(c, ChannelMoved::decode(&buf).unwrap())
.await;
});
true
}
b"notifychanneledited" => {
task::spawn(async move {
handler
.channeledited(c, ChannelEdited::decode(&buf).unwrap())
.await;
});
true
}
b"notifychannelcreated" => {
task::spawn(async move {
handler
.channelcreated(c, ChannelCreated::decode(&buf).unwrap())
.await;
});
true
}
b"notifychanneldeleted" => {
task::spawn(async move {
handler
.channeldeleted(c, ChannelDeleted::decode(&buf).unwrap())
.await;
});
true
}
b"notifyclientmoved" => {
task::spawn(async move {
handler.clientmoved(c, ClientMoved::decode(&buf).unwrap()).await;
});
true
}
b"notifytextmessage" => {
task::spawn(async move {
handler
.textmessage(c, TextMessage::decode(&buf).unwrap())
.await;
});
true
}
b"notifytokenused" => {
task::spawn(async move {
handler.tokenused(c, TokenUsed::decode(&buf).unwrap()).await;
});
true
}
_ => false,
}
}
}
#[async_trait]
pub trait EventHandler: Send + Sync {
async fn cliententerview(&self, _client: Client, _event: ClientEnterView) {}
async fn clientleftview(&self, _client: Client, _event: ClientLeftView) {}
async fn serveredited(&self, _client: Client, _event: ServerEdited) {}
async fn channeldescriptionchanged(&self, _client: Client, _event: ChannelDescriptionChanged) {}
async fn channelpasswordchanged(&self, _client: Client, _event: ChannelPasswordChanged) {}
async fn channelmoved(&self, _client: Client, _event: ChannelMoved) {}
async fn channeledited(&self, _client: Client, _event: ChannelEdited) {}
async fn channelcreated(&self, _client: Client, _event: ChannelCreated) {}
async fn channeldeleted(&self, _client: Client, _event: ChannelDeleted) {}
async fn clientmoved(&self, _client: Client, _event: ClientMoved) {}
async fn textmessage(&self, _client: Client, _event: TextMessage) {}
async fn tokenused(&self, _client: Client, _event: TokenUsed) {}
}
#[derive(Debug)]
pub enum ReasonID {
SwitchChannel = 0,
Moved,
Timeout,
ChannelKick,
ServerKick,
Ban,
ServerLeave,
Edited,
ServerShutdown,
}
impl Decode<ReasonID> for ReasonID {
type Err = <u8 as Decode<u8>>::Err;
fn decode(buf: &[u8]) -> Result<ReasonID, Self::Err> {
use ReasonID::*;
Ok(match u8::decode(buf)? {
0 => SwitchChannel,
1 => Moved,
2 => Timeout,
3 => ChannelKick,
4 => ServerKick,
5 => Ban,
6 => ServerLeave,
7 => Edited,
8 => ServerShutdown,
n => panic!("Unexpected Reasonid {}", n),
})
}
}
impl Default for ReasonID {
fn default() -> ReasonID {
ReasonID::SwitchChannel
}
}
impl FromStr for ReasonID {
type Err = ParseError;
fn from_str(s: &str) -> Result<ReasonID, Self::Err> {
match s {
"0" => Ok(ReasonID::SwitchChannel),
"1" => Ok(ReasonID::Moved),
"3" => Ok(ReasonID::Timeout),
"4" => Ok(ReasonID::ChannelKick),
"5" => Ok(ReasonID::ServerKick),
"6" => Ok(ReasonID::Ban),
"8" => Ok(ReasonID::ServerLeave),
"10" => Ok(ReasonID::Edited),
"11" => Ok(ReasonID::ServerShutdown),
_ => Err(ParseError::InvalidEnum),
}
}
}
#[derive(Debug, Decode, Default)]
pub struct ClientEnterView {
pub cfid: u64,
pub ctid: u64,
pub reasonid: ReasonID,
pub clid: u64,
pub client_unique_identifier: String,
pub client_nickname: String,
pub client_input_muted: bool,
pub client_output_muted: bool,
pub client_outputonly_muted: bool,
pub client_input_hardware: u64,
pub client_output_hardwarer: u64,
pub client_is_recording: bool,
pub client_database_id: u64,
pub client_channel_group_id: u64,
pub client_servergroups: Vec<u64>,
pub client_away: bool,
pub client_away_message: String,
pub client_type: u8,
pub client_talk_power: u64,
pub client_talk_request: bool,
pub client_talk_request_msg: String,
pub client_description: String,
pub client_is_talker: bool,
pub client_nickname_phoentic: String,
pub client_needed_serverquey_view_power: u64,
pub client_icon_id: u64,
pub client_country: String,
pub client_channel_group_inherited_channel_id: u64,
pub client_badges: String,
}
#[derive(Debug, Decode, Default)]
pub struct ClientLeftView {
pub cfid: usize,
pub ctid: usize,
pub reasonid: ReasonID,
pub invokerid: usize,
pub invokername: String,
pub invokeruid: String,
pub reasonmsg: String,
pub bantime: usize,
pub clid: usize,
}
#[derive(Debug, Decode, Default)]
pub struct ServerEdited {
pub reasonid: ReasonID,
pub invokerid: u64,
pub invokername: String,
pub invokeruid: String,
pub virtualserver_name: String,
pub virtualserver_codec_encryption_mode: String,
pub virtualserver_default_server_group: u64,
pub virtualserver_default_channel_group: u64,
pub virtualserver_hostbanner_url: String,
pub virtualserver_hostbanner_gfx_url: String,
pub virtualserver_hostbanner_gfx_interval: u64,
pub virtualserver_priority_speaker_dimm_modificator: String,
pub virtualserver_hostbutton_tooltip: String,
pub virtualserver_hostbutton_url: String,
pub virtualserver_hostbutton_gfx_url: String,
pub virtualserver_name_phoentic: String,
pub virtualserver_icon_id: u64,
pub virtualserver_hostbanner_mode: String,
pub virtualserver_channel_temp_delete_delay_default: u64,
}
#[derive(Debug, Decode, Default)]
pub struct ChannelDescriptionChanged {
pub cid: u64,
}
#[derive(Debug, Decode, Default)]
pub struct ChannelPasswordChanged {
pub cid: u64,
}
#[derive(Debug, Decode, Default)]
pub struct ChannelMoved {
pub cid: u64,
pub cpid: u64,
pub order: u64,
pub reasonid: ReasonID,
pub invokerid: u64,
pub invokername: String,
pub invokeruid: String,
}
#[derive(Debug, Decode, Default)]
pub struct ChannelEdited {
pub cid: u64,
pub reasonid: u64,
pub invokerid: u64,
pub invokername: String,
pub invokeruid: String,
pub channel_name: String,
pub channel_topic: String,
pub channel_codec: u8,
pub channel_codec_quality: u8,
pub channel_maxclients: u16,
pub channel_maxfamilyclients: u16,
pub channel_order: u64,
pub channel_flag_permanent: bool,
pub channel_flag_semi_permanent: bool,
pub channel_flag_default: bool,
pub channel_flag_password: String,
pub channel_codec_latency_factor: u64,
pub channel_codec_is_unencrypted: bool,
pub channel_delete_delay: u32,
pub channel_flag_maxclients_unlimited: bool,
pub channel_flag_maxfamilyclients_unlimited: bool,
pub channel_flag_maxfamilyclients_inherited: bool,
pub channel_needed_talk_power: u32,
pub channel_name_phonetic: String,
pub channel_icon_id: u64,
}
#[derive(Debug, Decode, Default)]
pub struct ChannelCreated {
pub cid: u64,
pub cpid: u64,
pub channel_name: String,
pub channel_topic: String,
pub channel_codec: u8,
pub channel_codec_quality: u8,
pub channel_maxclients: u16,
pub channel_maxfamilyclients: u16,
pub channel_order: u64,
pub channel_flag_permanent: bool,
pub channel_flag_semi_permanent: bool,
pub channel_flag_default: bool,
pub channel_flag_password: bool,
pub channel_codec_latency_factor: u64,
pub channel_codec_is_unencrypted: bool,
pub channel_delete_delay: u32,
pub channel_flag_maxclients_unlimited: bool,
pub channel_flag_maxfamilyclients_unlimited: bool,
pub channel_flag_maxfamilyclients_inherited: bool,
pub channel_needed_talk_power: u32,
pub channel_name_phonetic: String,
pub channel_icon_id: u64,
pub invokerid: u64,
pub invokername: String,
pub invokeruid: String,
}
#[derive(Debug, Decode, Default)]
pub struct ChannelDeleted {
pub invokerid: u64,
pub invokername: String,
pub invokeruid: String,
pub cid: u64,
}
#[derive(Debug, Decode, Default)]
pub struct ClientMoved {
pub ctid: u64,
pub reasonid: ReasonID,
pub invokerid: u64,
pub invokername: String,
pub invokeruid: String,
pub clid: u64,
}
#[derive(Debug, Decode, Default)]
pub struct TextMessage {
pub targetmode: usize,
pub msg: String,
pub target: usize,
pub invokerid: usize,
pub invokername: String,
pub invokeruid: String,
}
#[derive(Debug, Decode, Default)]
pub struct TokenUsed {
pub clid: u64,
pub cldbid: u64,
pub cluid: String,
pub token: String,
pub tokencustomset: String,
pub token1: u64,
pub token2: u64,
}
pub(crate) struct Handler;
impl EventHandler for Handler {}