Add event listener with JSON output (WIP) Add notifier on movement events Refactor Parameter and ParameterList (still shit)
This commit is contained in:
parent
2c0a8ab616
commit
d8cdc2bb11
14 changed files with 338 additions and 186 deletions
45
Cargo.lock
generated
45
Cargo.lock
generated
|
@ -102,6 +102,12 @@ version = "0.4.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "itoa"
|
||||||
|
version = "1.0.10"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "b1a46d1a171d865aa5f83f92695765caa047a9b4cbae2cbf37dbd613a793fd4c"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "proc-macro2"
|
name = "proc-macro2"
|
||||||
version = "1.0.69"
|
version = "1.0.69"
|
||||||
|
@ -120,6 +126,43 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ryu"
|
||||||
|
version = "1.0.17"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e86697c916019a8588c99b5fac3cead74ec0b4b819707a682fd4d23fa0ce1ba1"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde"
|
||||||
|
version = "1.0.193"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
|
||||||
|
dependencies = [
|
||||||
|
"serde_derive",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_derive"
|
||||||
|
version = "1.0.193"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
|
||||||
|
dependencies = [
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "serde_json"
|
||||||
|
version = "1.0.109"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cb0652c533506ad7a2e353cce269330d6afd8bdfb6d75e0ace5b35aacbd7b9e9"
|
||||||
|
dependencies = [
|
||||||
|
"itoa",
|
||||||
|
"ryu",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "strsim"
|
name = "strsim"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
|
@ -142,6 +185,8 @@ name = "teamspeak-query-lib"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"telnet",
|
"telnet",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
|
@ -6,3 +6,6 @@ edition = "2021"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
telnet = "0.2"
|
telnet = "0.2"
|
||||||
clap = { version = "4.4", features = ["derive"] }
|
clap = { version = "4.4", features = ["derive"] }
|
||||||
|
|
||||||
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
|
serde_json = "1.0"
|
||||||
|
|
34
src/cli.rs
34
src/cli.rs
|
@ -1,8 +1,8 @@
|
||||||
use clap::{Args, Parser, Subcommand};
|
use clap::{Args, Parser, Subcommand};
|
||||||
use telnet::Telnet;
|
use telnet::Telnet;
|
||||||
|
|
||||||
use crate::parameter::{Parameter, ParameterList};
|
use crate::parameter::ParameterList;
|
||||||
use crate::models::Channel;
|
use crate::models::{Channel, EventType};
|
||||||
use crate::models::Client;
|
use crate::models::Client;
|
||||||
use crate::utils::SendTextMessageTarget;
|
use crate::utils::SendTextMessageTarget;
|
||||||
use crate::wrappers;
|
use crate::wrappers;
|
||||||
|
@ -23,6 +23,7 @@ pub enum Commands {
|
||||||
Message(MessageArgs),
|
Message(MessageArgs),
|
||||||
Move(MoveArgs),
|
Move(MoveArgs),
|
||||||
Update(UpdateArgs),
|
Update(UpdateArgs),
|
||||||
|
Events(EventArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Args)]
|
#[derive(Args)]
|
||||||
|
@ -78,6 +79,11 @@ pub struct UpdateArgs {
|
||||||
speakers: Option<bool>,
|
speakers: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Args)]
|
||||||
|
pub struct EventArgs {
|
||||||
|
pub event: Vec<EventType>,
|
||||||
|
}
|
||||||
|
|
||||||
impl FetchArgs {
|
impl FetchArgs {
|
||||||
pub fn want_channel(&self) -> bool {
|
pub fn want_channel(&self) -> bool {
|
||||||
self.channel.is_some()
|
self.channel.is_some()
|
||||||
|
@ -89,14 +95,14 @@ impl FetchArgs {
|
||||||
|
|
||||||
pub fn channel(&self, connection: &mut Telnet) -> Result<Option<Channel>, String> {
|
pub fn channel(&self, connection: &mut Telnet) -> Result<Option<Channel>, String> {
|
||||||
if let Some(channel) = &self.channel {
|
if let Some(channel) = &self.channel {
|
||||||
wrappers::find_channel(connection, channel, self.strict_channel)
|
wrappers::find_channel(connection, "channel_name", channel, self.strict_channel)
|
||||||
} else {
|
} else {
|
||||||
Err("No channel specified.".to_string())
|
Err("No channel specified.".to_string())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn client(&self, connection: &mut Telnet) -> Result<Option<Client>, String> {
|
pub fn client(&self, connection: &mut Telnet) -> Result<Option<Client>, String> {
|
||||||
if let Some(client) = &self.client {
|
if let Some(client) = &self.client {
|
||||||
wrappers::find_client(connection, client, self.strict_client)
|
wrappers::find_client(connection, "client_nickname", client, self.strict_client)
|
||||||
} else {
|
} else {
|
||||||
Err("No client specified.".to_string())
|
Err("No client specified.".to_string())
|
||||||
}
|
}
|
||||||
|
@ -108,7 +114,7 @@ impl MessageArgs {
|
||||||
if self.server {
|
if self.server {
|
||||||
Ok(SendTextMessageTarget::Server)
|
Ok(SendTextMessageTarget::Server)
|
||||||
} else if let Some(client) = &self.client {
|
} else if let Some(client) = &self.client {
|
||||||
if let Some(client) = wrappers::find_client(connection, client, self.strict_client)? {
|
if let Some(client) = wrappers::find_client(connection, "client_nickname", client, self.strict_client)? {
|
||||||
return Ok(SendTextMessageTarget::Client(client));
|
return Ok(SendTextMessageTarget::Client(client));
|
||||||
}
|
}
|
||||||
return Err("Could not find client.".to_string());
|
return Err("Could not find client.".to_string());
|
||||||
|
@ -120,12 +126,12 @@ impl MessageArgs {
|
||||||
|
|
||||||
impl MoveArgs {
|
impl MoveArgs {
|
||||||
pub fn channel(&self, connection: &mut Telnet) -> Result<Option<Channel>, String> {
|
pub fn channel(&self, connection: &mut Telnet) -> Result<Option<Channel>, String> {
|
||||||
wrappers::find_channel(connection, &self.channel, self.strict_channel)
|
wrappers::find_channel(connection, "channel_name", &self.channel, self.strict_channel)
|
||||||
}
|
}
|
||||||
pub fn client(&self, connection: &mut Telnet) -> Result<Option<Client>, String> {
|
pub fn client(&self, connection: &mut Telnet) -> Result<Option<Client>, String> {
|
||||||
match &self.client {
|
match &self.client {
|
||||||
Some(client) => {
|
Some(client) => {
|
||||||
wrappers::find_client(connection, client, self.strict_client)
|
wrappers::find_client(connection, "client_nickname", client, self.strict_client)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
match wrappers::find_self(connection) {
|
match wrappers::find_self(connection) {
|
||||||
|
@ -139,25 +145,25 @@ impl MoveArgs {
|
||||||
|
|
||||||
impl UpdateArgs {
|
impl UpdateArgs {
|
||||||
pub fn to_parameter_list(&self) -> ParameterList {
|
pub fn to_parameter_list(&self) -> ParameterList {
|
||||||
let mut params: ParameterList = Vec::new();
|
let mut params: ParameterList = ParameterList::new();
|
||||||
|
|
||||||
if let Some(name) = &self.name {
|
if let Some(name) = &self.name {
|
||||||
params.push(Parameter::new("client_nickname", name));
|
params.insert(String::from("client_nickname"), name.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(away) = &self.away {
|
if let Some(away) = &self.away {
|
||||||
params.push(Parameter::new("client_away_message", away));
|
params.insert(String::from("client_away_message"), away.clone());
|
||||||
params.push(Parameter::new("client_away", "1"));
|
params.insert(String::from("client_away"), String::from("1"));
|
||||||
}
|
}
|
||||||
if self.back {
|
if self.back {
|
||||||
params.push(Parameter::new("client_away", "0"));
|
params.insert(String::from("client_away"), String::from("0"));
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(microphone) = self.microphone {
|
if let Some(microphone) = self.microphone {
|
||||||
params.push(Parameter::new("client_input_muted", &u8::from(!microphone).to_string()));
|
params.insert(String::from("client_input_muted"), u8::from(!microphone).to_string());
|
||||||
}
|
}
|
||||||
if let Some(speakers) = self.speakers {
|
if let Some(speakers) = self.speakers {
|
||||||
params.push(Parameter::new("client_output_muted", &u8::from(!speakers).to_string()));
|
params.insert(String::from("client_output_muted"), u8::from(!speakers).to_string());
|
||||||
}
|
}
|
||||||
|
|
||||||
params
|
params
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use crate::utils::SendTextMessageTarget;
|
use crate::utils::SendTextMessageTarget;
|
||||||
use telnet::Event::Data;
|
use telnet::Event::Data;
|
||||||
use telnet::Telnet;
|
use telnet::Telnet;
|
||||||
|
use crate::models::EventType;
|
||||||
|
|
||||||
use crate::parameter::{Parameter, ParameterList};
|
use crate::parameter::{Parameter, parameters_to_string, ParameterList, parameter_to_string, parameter_list_to_string};
|
||||||
use crate::response::Response;
|
use crate::response::Response;
|
||||||
|
|
||||||
fn to_single_response(resp: Response) -> Response {
|
fn to_single_response(resp: Response) -> Response {
|
||||||
|
@ -48,7 +49,7 @@ fn send_command(connection: &mut Telnet, command: &str, skip_ok: bool) -> Result
|
||||||
read_response(connection, skip_ok, String::new())
|
read_response(connection, skip_ok, String::new())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_response(connection: &mut Telnet, skip_ok: bool, mut buffer: String) -> Result<Response, String> {
|
pub fn read_response(connection: &mut Telnet, skip_ok: bool, mut buffer: String) -> Result<Response, String> {
|
||||||
let (response_str, buffer) = read_response_buffer(connection, &mut buffer)?;
|
let (response_str, buffer) = read_response_buffer(connection, &mut buffer)?;
|
||||||
|
|
||||||
match Response::try_from(response_str) {
|
match Response::try_from(response_str) {
|
||||||
|
@ -93,18 +94,22 @@ pub fn whoami(connection: &mut Telnet) -> Result<Response, String> {
|
||||||
pub fn clientmove(connection: &mut Telnet, cid: &i32, clid_list: Vec<&i32>) -> Result<Response, String> {
|
pub fn clientmove(connection: &mut Telnet, cid: &i32, clid_list: Vec<&i32>) -> Result<Response, String> {
|
||||||
let clid_param_list = clid_list
|
let clid_param_list = clid_list
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|clid| Parameter::new("clid", &clid.to_string()))
|
.map(|clid| (String::from("clid"), clid.to_string()))
|
||||||
.collect::<Vec<Parameter>>();
|
.collect::<Vec<Parameter>>();
|
||||||
let clid_str = Parameter::list_to_string_sep(clid_param_list, "|");
|
let clid_str = parameters_to_string(clid_param_list, "|");
|
||||||
send_command(connection, &format!("clientmove cid={} {}", cid, clid_str), false)
|
send_command(connection, &format!("clientmove cid={} {}", cid, clid_str), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn clientupdate(connection: &mut Telnet, parameters: ParameterList) -> Result<Response, String> {
|
pub fn clientupdate(connection: &mut Telnet, parameters: ParameterList) -> Result<Response, String> {
|
||||||
let parameters_str = Parameter::list_to_string(parameters);
|
let parameters_str = parameter_list_to_string(parameters, " ");
|
||||||
send_command(connection, &format!("clientupdate {}", parameters_str), false)
|
send_command(connection, &format!("clientupdate {}", parameters_str), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sendtextmessage(connection: &mut Telnet, target: SendTextMessageTarget, msg: String) -> Result<Response, String> {
|
pub fn sendtextmessage(connection: &mut Telnet, target: SendTextMessageTarget, msg: String) -> Result<Response, String> {
|
||||||
let msg = String::from(Parameter::new("msg", &msg));
|
let msg = parameter_to_string((String::from("msg"), msg));
|
||||||
send_command(connection, &format!("sendtextmessage {} {}", msg, String::from(target)), false)
|
send_command(connection, &format!("sendtextmessage {} {}", msg, String::from(target)), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn clientnotifyregister(connection: &mut Telnet, schandlerid: u32, event: EventType) -> Result<Response, String> {
|
||||||
|
send_command(connection, &format!("clientnotifyregister schandlerid={} event={}", schandlerid, String::from(&event)), false)
|
||||||
|
}
|
||||||
|
|
35
src/main.rs
35
src/main.rs
|
@ -3,8 +3,9 @@ use std::process::exit;
|
||||||
use telnet::Telnet;
|
use telnet::Telnet;
|
||||||
|
|
||||||
use crate::cli::Commands;
|
use crate::cli::Commands;
|
||||||
use crate::models::Channel;
|
use crate::models::{Channel, Event};
|
||||||
use crate::models::Client;
|
use crate::models::Client;
|
||||||
|
use crate::response::Response;
|
||||||
|
|
||||||
mod wrappers;
|
mod wrappers;
|
||||||
mod commands;
|
mod commands;
|
||||||
|
@ -49,8 +50,6 @@ fn main() {
|
||||||
wrappers::skip_welcome(&mut connection);
|
wrappers::skip_welcome(&mut connection);
|
||||||
wrappers::login(&mut connection);
|
wrappers::login(&mut connection);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// You can check for the existence of subcommands, and if found use their
|
// You can check for the existence of subcommands, and if found use their
|
||||||
// matches just as you would the top level cmd
|
// matches just as you would the top level cmd
|
||||||
match cli {
|
match cli {
|
||||||
|
@ -154,5 +153,35 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Commands::Events(args) => {
|
||||||
|
for event in args.event {
|
||||||
|
if commands::clientnotifyregister(&mut connection, 1, event).is_err() {
|
||||||
|
println!("Failed to register event listener.");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
loop {
|
||||||
|
match commands::read_response(&mut connection, true, String::new()) {
|
||||||
|
Ok(response) => {
|
||||||
|
if let Response::Event(event_type, params) = response {
|
||||||
|
|
||||||
|
let event = Event::new(&mut connection, event_type, params);
|
||||||
|
match serde_json::to_string(&event) {
|
||||||
|
Ok(json) => println!("{}", json),
|
||||||
|
Err(_) => {
|
||||||
|
// TODO: Handle error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(_) => {
|
||||||
|
// TODO: Handle error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,9 @@
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::parameter::{parameter_find, ParameterList};
|
use crate::parameter::{parameter_find, ParameterList};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Channel {
|
pub struct Channel {
|
||||||
pub cid: i32,
|
pub cid: i32,
|
||||||
pub pid: i32,
|
pub pid: i32,
|
||||||
|
@ -23,22 +24,20 @@ impl From<ParameterList> for Channel {
|
||||||
Channel {
|
Channel {
|
||||||
cid: parameter_find(&value, "cid")
|
cid: parameter_find(&value, "cid")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(-1),
|
.parse::<i32>().unwrap_or(-1),
|
||||||
pid: parameter_find(&value, "pid")
|
pid: parameter_find(&value, "pid")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(-1),
|
.parse::<i32>().unwrap_or(-1),
|
||||||
channel_order: parameter_find(&value, "channel_order")
|
channel_order: parameter_find(&value, "channel_order")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(-1),
|
.parse::<i32>().unwrap_or(-1),
|
||||||
channel_name: parameter_find(&value, "channel_name")
|
channel_name: parameter_find(&value, "channel_name")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default(),
|
||||||
.value,
|
|
||||||
channel_topic: parameter_find(&value, "channel_topic")
|
channel_topic: parameter_find(&value, "channel_topic")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default(),
|
||||||
.value,
|
|
||||||
channel_flag_are_subscribed: parameter_find(&value, "channel_flag_are_subscribed")
|
channel_flag_are_subscribed: parameter_find(&value, "channel_flag_are_subscribed")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(0) == 1,
|
.parse::<i32>().unwrap_or(0) == 1,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
use crate::parameter::{parameter_find, ParameterList};
|
use crate::parameter::{parameter_find, ParameterList};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub struct Client {
|
pub struct Client {
|
||||||
pub cid: i32,
|
pub cid: i32,
|
||||||
pub clid: i32,
|
pub clid: i32,
|
||||||
|
@ -22,19 +23,18 @@ impl From<ParameterList> for Client {
|
||||||
Client {
|
Client {
|
||||||
cid: parameter_find(&value, "cid")
|
cid: parameter_find(&value, "cid")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(-1),
|
.parse::<i32>().unwrap_or(-1),
|
||||||
clid: parameter_find(&value, "clid")
|
clid: parameter_find(&value, "clid")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(-1),
|
.parse::<i32>().unwrap_or(-1),
|
||||||
client_database_id: parameter_find(&value, "client_database_id")
|
client_database_id: parameter_find(&value, "client_database_id")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(-1),
|
.parse::<i32>().unwrap_or(-1),
|
||||||
client_nickname: parameter_find(&value, "client_nickname")
|
client_nickname: parameter_find(&value, "client_nickname")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default(),
|
||||||
.value,
|
|
||||||
client_type: parameter_find(&value, "channel_topic")
|
client_type: parameter_find(&value, "channel_topic")
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.to_i32(0),
|
.parse::<i32>().unwrap_or(0),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,16 @@
|
||||||
use std::fmt::{Display, Formatter};
|
use std::fmt::{Display, Formatter};
|
||||||
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Debug)]
|
use serde::{Deserialize, Serialize};
|
||||||
pub enum Event {
|
use telnet::Telnet;
|
||||||
|
|
||||||
|
use crate::models::{Channel, Client};
|
||||||
|
use crate::parameter::{parameter_find, ParameterList};
|
||||||
|
use crate::wrappers;
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
||||||
|
pub enum EventType {
|
||||||
|
Any,
|
||||||
ChannelList,
|
ChannelList,
|
||||||
ChannelListFinished,
|
ChannelListFinished,
|
||||||
NotifyTalkStatusChange,
|
NotifyTalkStatusChange,
|
||||||
|
@ -16,6 +25,7 @@ pub enum Event {
|
||||||
NotifyClientChatClosed,
|
NotifyClientChatClosed,
|
||||||
NotifyClientChatComposing,
|
NotifyClientChatComposing,
|
||||||
NotifyClientUpdated,
|
NotifyClientUpdated,
|
||||||
|
NotifyClientChannelGroupChanged,
|
||||||
NotifyClientIds,
|
NotifyClientIds,
|
||||||
NotifyClientDBIDFromUid,
|
NotifyClientDBIDFromUid,
|
||||||
NotifyClientNameFromUid,
|
NotifyClientNameFromUid,
|
||||||
|
@ -33,51 +43,151 @@ pub enum Event {
|
||||||
NotifyConnectStatusChange,
|
NotifyConnectStatusChange,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for Event {
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub struct Event {
|
||||||
|
pub event_type: EventType,
|
||||||
|
pub params: ParameterList,
|
||||||
|
pub channel: Option<Channel>,
|
||||||
|
pub client: Option<Client>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<&str> for EventType {
|
||||||
type Error = String;
|
type Error = String;
|
||||||
|
|
||||||
//noinspection SpellCheckingInspection
|
//noinspection SpellCheckingInspection
|
||||||
fn try_from(event_type: &str) -> Result<Self, Self::Error> {
|
fn try_from(event_type: &str) -> Result<Self, Self::Error> {
|
||||||
match event_type {
|
match event_type.to_lowercase().as_str() {
|
||||||
"channellist" => Ok(Event::ChannelList),
|
"any" => Ok(EventType::Any),
|
||||||
"channellistfinished" => Ok(Event::ChannelListFinished),
|
"channellist" => Ok(EventType::ChannelList),
|
||||||
"notifytalkstatuschange" => Ok(Event::NotifyTalkStatusChange),
|
"channellistfinished" => Ok(EventType::ChannelListFinished),
|
||||||
"notifymessage" => Ok(Event::NotifyMessage),
|
"notifytalkstatuschange" => Ok(EventType::NotifyTalkStatusChange),
|
||||||
"notifymessagelist" => Ok(Event::NotifyMessageList),
|
"notifymessage" => Ok(EventType::NotifyMessage),
|
||||||
"notifycomplainlist" => Ok(Event::NotifyComplainList),
|
"notifymessagelist" => Ok(EventType::NotifyMessageList),
|
||||||
"notifybanlist" => Ok(Event::NotifyBanList),
|
"notifycomplainlist" => Ok(EventType::NotifyComplainList),
|
||||||
"notifyclientmoved" => Ok(Event::NotifyClientMoved),
|
"notifybanlist" => Ok(EventType::NotifyBanList),
|
||||||
"notifyclientleftview" => Ok(Event::NotifyClientLeftView),
|
"notifyclientmoved" => Ok(EventType::NotifyClientMoved),
|
||||||
"notifycliententerview" => Ok(Event::NotifyClientEnterView),
|
"notifyclientleftview" => Ok(EventType::NotifyClientLeftView),
|
||||||
"notifyclientpoke" => Ok(Event::NotifyClientPoke),
|
"notifycliententerview" => Ok(EventType::NotifyClientEnterView),
|
||||||
"notifyclientchatclosed" => Ok(Event::NotifyClientChatClosed),
|
"notifyclientpoke" => Ok(EventType::NotifyClientPoke),
|
||||||
"notifyclientchatcomposing" => Ok(Event::NotifyClientChatComposing),
|
"notifyclientchatclosed" => Ok(EventType::NotifyClientChatClosed),
|
||||||
"notifyclientupdated" => Ok(Event::NotifyClientUpdated),
|
"notifyclientchatcomposing" => Ok(EventType::NotifyClientChatComposing),
|
||||||
"notifyclientids" => Ok(Event::NotifyClientIds),
|
"notifyclientupdated" => Ok(EventType::NotifyClientUpdated),
|
||||||
"notifyclientdbidfromuid" => Ok(Event::NotifyClientDBIDFromUid),
|
"notifyclientchannelgroupchanged" => Ok(EventType::NotifyClientChannelGroupChanged),
|
||||||
"notifyclientnamefromuid" => Ok(Event::NotifyClientNameFromUid),
|
"notifyclientids" => Ok(EventType::NotifyClientIds),
|
||||||
"notifyclientnamefromdbid" => Ok(Event::NotifyClientNameFromDBID),
|
"notifyclientdbidfromuid" => Ok(EventType::NotifyClientDBIDFromUid),
|
||||||
"notifyclientuidfromclid" => Ok(Event::NotifyClientUidFromClid),
|
"notifyclientnamefromuid" => Ok(EventType::NotifyClientNameFromUid),
|
||||||
"notifyconnectioninfo" => Ok(Event::NotifyConnectionInfo),
|
"notifyclientnamefromdbid" => Ok(EventType::NotifyClientNameFromDBID),
|
||||||
"notifychannelcreated" => Ok(Event::NotifyChannelCreated),
|
"notifyclientuidfromclid" => Ok(EventType::NotifyClientUidFromClid),
|
||||||
"notifychanneledited" => Ok(Event::NotifyChannelEdited),
|
"notifyconnectioninfo" => Ok(EventType::NotifyConnectionInfo),
|
||||||
"notifychanneldeleted" => Ok(Event::NotifyChannelDeleted),
|
"notifychannelcreated" => Ok(EventType::NotifyChannelCreated),
|
||||||
"notifychannelmoved" => Ok(Event::NotifyChannelMoved),
|
"notifychanneledited" => Ok(EventType::NotifyChannelEdited),
|
||||||
"notifyserveredited" => Ok(Event::NotifyServerEdited),
|
"notifychanneldeleted" => Ok(EventType::NotifyChannelDeleted),
|
||||||
"notifyserverupdated" => Ok(Event::NotifyServerUpdated),
|
"notifychannelmoved" => Ok(EventType::NotifyChannelMoved),
|
||||||
"notifytextmessage" => Ok(Event::NotifyTextMessage),
|
"notifyserveredited" => Ok(EventType::NotifyServerEdited),
|
||||||
|
"notifyserverupdated" => Ok(EventType::NotifyServerUpdated),
|
||||||
|
"notifytextmessage" => Ok(EventType::NotifyTextMessage),
|
||||||
"notifycurrentserverconnectionchanged" => {
|
"notifycurrentserverconnectionchanged" => {
|
||||||
Ok(Event::NotifyCurrentServerConnectionChanged)
|
Ok(EventType::NotifyCurrentServerConnectionChanged)
|
||||||
}
|
}
|
||||||
"notifyconnectstatuschange" => Ok(Event::NotifyConnectStatusChange),
|
"notifyconnectstatuschange" => Ok(EventType::NotifyConnectStatusChange),
|
||||||
_ => Err(String::from("Unknown event type.")),
|
_ => Err(format!("Unknown event type: {}", event_type)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FromStr for EventType {
|
||||||
|
type Err = String;
|
||||||
|
|
||||||
impl Display for Event {
|
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
EventType::try_from(s)
|
||||||
write!(f, "{:?}", self)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<&EventType> for String {
|
||||||
|
//noinspection SpellCheckingInspection
|
||||||
|
fn from(value: &EventType) -> Self {
|
||||||
|
match value {
|
||||||
|
EventType::Any => String::from("any"),
|
||||||
|
EventType::ChannelList => String::from("channellist"),
|
||||||
|
EventType::ChannelListFinished => String::from("channellistfinished"),
|
||||||
|
EventType::NotifyTalkStatusChange => String::from("notifytalkstatuschange"),
|
||||||
|
EventType::NotifyMessage => String::from("notifymessage"),
|
||||||
|
EventType::NotifyMessageList => String::from("notifymessagelist"),
|
||||||
|
EventType::NotifyComplainList => String::from("notifycomplainlist"),
|
||||||
|
EventType::NotifyBanList => String::from("notifybanlist"),
|
||||||
|
EventType::NotifyClientMoved => String::from("notifyclientmoved"),
|
||||||
|
EventType::NotifyClientLeftView => String::from("notifyclientleftview"),
|
||||||
|
EventType::NotifyClientEnterView => String::from("notifycliententerview"),
|
||||||
|
EventType::NotifyClientPoke => String::from("notifyclientpoke"),
|
||||||
|
EventType::NotifyClientChatClosed => String::from("notifyclientchatclosed"),
|
||||||
|
EventType::NotifyClientChatComposing => String::from("notifyclientchatcomposing"),
|
||||||
|
EventType::NotifyClientChannelGroupChanged => String::from("notifyclientchannelgroupchanged"),
|
||||||
|
EventType::NotifyClientUpdated => String::from("notifyclientupdated"),
|
||||||
|
EventType::NotifyClientIds => String::from("notifyclientids"),
|
||||||
|
EventType::NotifyClientDBIDFromUid => String::from("notifyclientdbidfromuid"),
|
||||||
|
EventType::NotifyClientNameFromUid => String::from("notifyclientnamefromuid"),
|
||||||
|
EventType::NotifyClientNameFromDBID => String::from("notifyclientnamefromdbid"),
|
||||||
|
EventType::NotifyClientUidFromClid => String::from("notifyclientuidfromclid"),
|
||||||
|
EventType::NotifyConnectionInfo => String::from("notifyconnectioninfo"),
|
||||||
|
EventType::NotifyChannelCreated => String::from("notifychannelcreated"),
|
||||||
|
EventType::NotifyChannelEdited => String::from("notifychanneledited"),
|
||||||
|
EventType::NotifyChannelDeleted => String::from("notifychanneldeleted"),
|
||||||
|
EventType::NotifyChannelMoved => String::from("notifychannelmoved"),
|
||||||
|
EventType::NotifyServerEdited => String::from("notifyserveredited"),
|
||||||
|
EventType::NotifyServerUpdated => String::from("notifyserverupdated"),
|
||||||
|
EventType::NotifyTextMessage => String::from("notifytextmessage"),
|
||||||
|
EventType::NotifyCurrentServerConnectionChanged => {
|
||||||
|
String::from("notifycurrentserverconnectionchanged")
|
||||||
|
}
|
||||||
|
EventType::NotifyConnectStatusChange => String::from("notifyconnectstatuschange"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Display for EventType {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let event_str: String = self.into();
|
||||||
|
write!(f, "{}", event_str)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EventType {
|
||||||
|
pub fn get_channel(&self, connection: &mut Telnet, params: &ParameterList) -> Option<Channel> {
|
||||||
|
match self {
|
||||||
|
EventType::NotifyClientMoved => {
|
||||||
|
let id = parameter_find(params, "ctid")?
|
||||||
|
.parse::<i32>().unwrap_or(0);
|
||||||
|
wrappers::find_channel(connection, "cid", &id.to_string(), true).unwrap().or(None)
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_client(&self, connection: &mut Telnet, params: &ParameterList) -> Option<Client> {
|
||||||
|
match self {
|
||||||
|
EventType::NotifyClientMoved => {
|
||||||
|
let id = parameter_find(params, "clid")?
|
||||||
|
.parse::<i32>().unwrap_or(0);
|
||||||
|
wrappers::find_client(connection, "clid", &id.to_string(), true).unwrap().or(None)
|
||||||
|
}
|
||||||
|
EventType::NotifyClientEnterView => {
|
||||||
|
Some(Client::from(params.clone()))
|
||||||
|
}
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Event {
|
||||||
|
pub fn new(connection: &mut Telnet, event_type: EventType, params: ParameterList) -> Event {
|
||||||
|
let channel = event_type.get_channel(connection, ¶ms);
|
||||||
|
let client = event_type.get_client(connection, ¶ms);
|
||||||
|
|
||||||
|
Event {
|
||||||
|
event_type,
|
||||||
|
params,
|
||||||
|
channel,
|
||||||
|
client,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,4 +4,4 @@ mod event;
|
||||||
|
|
||||||
pub use channel::Channel;
|
pub use channel::Channel;
|
||||||
pub use client::Client;
|
pub use client::Client;
|
||||||
pub use event::Event;
|
pub use event::{EventType, Event};
|
119
src/parameter.rs
119
src/parameter.rs
|
@ -1,36 +1,38 @@
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::collections::HashMap;
|
||||||
use crate::utils::{decode_value, encode_value};
|
use crate::utils::{decode_value, encode_value};
|
||||||
|
|
||||||
#[derive(Clone)]
|
pub type ParameterList = HashMap<String, String>;
|
||||||
pub struct Parameter {
|
pub type Parameter = (String, String);
|
||||||
pub name: String,
|
|
||||||
pub value: String,
|
pub fn parameter_find(params: &ParameterList, name: &str) -> Option<String> {
|
||||||
|
params.get(name).map(|value| value.clone())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ParameterList = Vec<Parameter>;
|
pub fn parameter_list_has(params: &ParameterList, key: &str, value: &str, strict: bool) -> bool {
|
||||||
|
if let Some(check_value) = params.get(key) {
|
||||||
pub fn parameter_find(params: &Vec<Parameter>, name: &str) -> Option<Parameter> {
|
if check_value == value && strict {
|
||||||
for param in params {
|
return true;
|
||||||
if param.name == name {
|
}
|
||||||
return Some(param.clone());
|
if check_value.contains(value) && !strict {
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parameter_list_find(param_lists: &Vec<ParameterList>, name: &str, value: &str, strict: bool) -> Option<ParameterList> {
|
pub fn parameter_list_find(param_lists: &Vec<ParameterList>, key: &str, value: &str, strict: bool) -> Option<ParameterList> {
|
||||||
for params in param_lists {
|
for params in param_lists {
|
||||||
if params.iter().any(|param| param.is(name, value, strict)) {
|
if parameter_list_has(params, key, value, strict) {
|
||||||
return Some(params.clone());
|
return Some(params.clone());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn parameter_list_find_all(param_lists: &Vec<ParameterList>, name: &str, value: &str, strict: bool) -> Vec<ParameterList> {
|
pub fn parameter_list_find_all(param_lists: &Vec<ParameterList>, key: &str, value: &str, strict: bool) -> Vec<ParameterList> {
|
||||||
let mut found = Vec::new();
|
let mut found = Vec::new();
|
||||||
for params in param_lists {
|
for params in param_lists {
|
||||||
if params.iter().any(|param| param.is(name, value, strict)) {
|
if parameter_list_has(params, key, value, strict) {
|
||||||
found.push(params.clone())
|
found.push(params.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,82 +42,31 @@ pub fn parameter_list_find_all(param_lists: &Vec<ParameterList>, name: &str, val
|
||||||
pub fn parameter_parse(params_str: &str) -> ParameterList {
|
pub fn parameter_parse(params_str: &str) -> ParameterList {
|
||||||
let parts: Vec<&str> = params_str.split(' ').collect();
|
let parts: Vec<&str> = params_str.split(' ').collect();
|
||||||
|
|
||||||
let mut response_params = Vec::new();
|
let mut response_params = ParameterList::new();
|
||||||
parts.iter().for_each(|part| {
|
parts.iter().for_each(|part| {
|
||||||
response_params.push(Parameter::from(part.split_once('=').unwrap()));
|
let (key, value) = part.split_once('=').unwrap_or((part, "1"));
|
||||||
|
response_params.insert(key.to_string(), decode_value(value));
|
||||||
});
|
});
|
||||||
|
|
||||||
response_params
|
response_params
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<(&str, &str)> for Parameter {
|
pub fn parameter_to_string(param: Parameter) -> String {
|
||||||
fn from(param: (&str, &str)) -> Parameter {
|
format!("{}={}", param.0, encode_value(¶m.1))
|
||||||
Parameter::new(param.0, param.1)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Parameter {
|
pub fn parameter_list_to_string(parameter_list: ParameterList, sep: &str) -> String {
|
||||||
pub fn new(name: &str, value: &str) -> Parameter {
|
parameter_list
|
||||||
Parameter {
|
.into_iter()
|
||||||
name: String::from(name),
|
.map(|param| parameter_to_string(param))
|
||||||
value: decode_value(value)
|
.collect::<Vec<String>>()
|
||||||
}
|
.join(sep)
|
||||||
}
|
|
||||||
|
|
||||||
pub fn is(&self, name: &str, value: &str, strict: bool) -> bool {
|
|
||||||
if self.name != name {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if self.value != value && strict {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if !self.value.contains(value) && !strict {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_i32(&self, default: i32) -> i32 {
|
|
||||||
self.value.parse::<i32>().unwrap_or(default)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_to_string(parameter_list: ParameterList) -> String {
|
|
||||||
parameter_list
|
|
||||||
.into_iter()
|
|
||||||
.map(String::from)
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(" ")
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn list_to_string_sep(parameter_list: ParameterList, sep: &str) -> String {
|
|
||||||
parameter_list
|
|
||||||
.into_iter()
|
|
||||||
.map(String::from)
|
|
||||||
.collect::<Vec<String>>()
|
|
||||||
.join(sep)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Parameter {
|
pub fn parameters_to_string(parameters: Vec<Parameter>, sep: &str) -> String {
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
parameters
|
||||||
write!(f, "{}={}", self.name, self.value)
|
.into_iter()
|
||||||
}
|
.map(|param| parameter_to_string(param))
|
||||||
}
|
.collect::<Vec<String>>()
|
||||||
|
.join(sep)
|
||||||
impl Debug for Parameter {
|
|
||||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
|
||||||
write!(f, "{}={}", self.name, self.value)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for Parameter {
|
|
||||||
fn default() -> Self {
|
|
||||||
Parameter::new("", "")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Parameter> for String {
|
|
||||||
fn from(value: Parameter) -> Self {
|
|
||||||
format!("{}={}", value.name, encode_value(&value.value))
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
use std::fmt::{Debug, Display, Formatter};
|
use std::fmt::{Debug, Display, Formatter};
|
||||||
use crate::models::Event;
|
use crate::models::EventType;
|
||||||
|
|
||||||
use crate::parameter::*;
|
use crate::parameter::*;
|
||||||
|
|
||||||
|
@ -7,12 +7,12 @@ pub enum Response {
|
||||||
Ok,
|
Ok,
|
||||||
Data(ParameterList),
|
Data(ParameterList),
|
||||||
DataList(Vec<ParameterList>),
|
DataList(Vec<ParameterList>),
|
||||||
Event(Event, ParameterList),
|
Event(EventType, ParameterList),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub enum ResponseType {
|
pub enum ResponseType {
|
||||||
Error,
|
Error,
|
||||||
Event(Event),
|
Event(EventType),
|
||||||
Data,
|
Data,
|
||||||
Unknown,
|
Unknown,
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ fn get_response_type(type_str: &str) -> Result<ResponseType, String> {
|
||||||
return Ok(ResponseType::Error);
|
return Ok(ResponseType::Error);
|
||||||
}
|
}
|
||||||
if type_str.starts_with("notify") || type_str == "channellist" || type_str == "channellistfinished" {
|
if type_str.starts_with("notify") || type_str == "channellist" || type_str == "channellistfinished" {
|
||||||
let event_type = Event::try_from(type_str)?;
|
let event_type = EventType::try_from(type_str)?;
|
||||||
return Ok(ResponseType::Event(event_type));
|
return Ok(ResponseType::Event(event_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,16 +120,16 @@ impl Display for Response {
|
||||||
write!(f, "Ok")
|
write!(f, "Ok")
|
||||||
}
|
}
|
||||||
Response::Data(params) => {
|
Response::Data(params) => {
|
||||||
for param in params {
|
for param in params.clone() {
|
||||||
write!(f, "{};", param)?;
|
write!(f, "{};", parameter_to_string(param))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
Response::DataList(params_list) => {
|
Response::DataList(params_list) => {
|
||||||
for params in params_list {
|
for params in params_list {
|
||||||
write!(f, "[")?;
|
write!(f, "[")?;
|
||||||
for param in params {
|
for param in params.clone() {
|
||||||
write!(f, "{};", param)?;
|
write!(f, "{};", parameter_to_string(param))?;
|
||||||
}
|
}
|
||||||
write!(f, "]")?;
|
write!(f, "]")?;
|
||||||
}
|
}
|
||||||
|
@ -137,8 +137,8 @@ impl Display for Response {
|
||||||
}
|
}
|
||||||
Response::Event(event, params) => {
|
Response::Event(event, params) => {
|
||||||
write!(f, "Event: {}", event)?;
|
write!(f, "Event: {}", event)?;
|
||||||
for param in params {
|
for param in params.clone() {
|
||||||
write!(f, "{};", param)?;
|
write!(f, "{};", parameter_to_string(param))?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -151,14 +151,13 @@ impl ResponseError {
|
||||||
self.id == 0
|
self.id == 0
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_error(params: &Vec<Parameter>) -> ResponseError {
|
fn create_error(params: &ParameterList) -> ResponseError {
|
||||||
ResponseError {
|
ResponseError {
|
||||||
id: parameter_find(params, "id")
|
id: parameter_find(params, "id")
|
||||||
.unwrap_or_else(|| Parameter::new("id", "-1"))
|
.unwrap_or_else(|| String::from("-1"))
|
||||||
.to_i32(-1),
|
.parse::<i32>().unwrap_or(-1),
|
||||||
msg: parameter_find(params, "msg")
|
msg: parameter_find(params, "msg")
|
||||||
.unwrap_or_else(|| Parameter::new("msg", "Unknown error."))
|
.unwrap_or_else(|| String::from("Unknown error."))
|
||||||
.value,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
10
src/utils.rs
10
src/utils.rs
|
@ -1,5 +1,5 @@
|
||||||
use crate::models::Client;
|
use crate::models::Client;
|
||||||
use crate::parameter::Parameter;
|
use crate::parameter::parameters_to_string;
|
||||||
|
|
||||||
pub fn decode_value(value: &str) -> String {
|
pub fn decode_value(value: &str) -> String {
|
||||||
value
|
value
|
||||||
|
@ -32,9 +32,9 @@ impl From<SendTextMessageTarget> for String {
|
||||||
_ => String::from("0"),
|
_ => String::from("0"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Parameter::list_to_string(vec![
|
parameters_to_string(vec![
|
||||||
Parameter::new("targetmode", target_mode),
|
(String::from("targetmode"), String::from(target_mode)),
|
||||||
Parameter::new("target", &target)
|
(String::from("target"), target)
|
||||||
])
|
], " ")
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -57,10 +57,10 @@ pub fn get_channels(connection: &mut Telnet, spacers: bool) -> Result<Vec<Channe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_channel(connection: &mut Telnet, name: &str, strict: bool) -> Result<Option<Channel>, String> {
|
pub fn find_channel(connection: &mut Telnet, key: &str, value: &str, strict: bool) -> Result<Option<Channel>, String> {
|
||||||
match commands::channellist(connection)? {
|
match commands::channellist(connection)? {
|
||||||
Response::DataList(parameter_lists) => {
|
Response::DataList(parameter_lists) => {
|
||||||
match parameter::parameter_list_find(¶meter_lists, "channel_name", name, strict) {
|
match parameter::parameter_list_find(¶meter_lists, key, value, strict) {
|
||||||
Some(params) => {
|
Some(params) => {
|
||||||
Ok(Some(Channel::from(params)))
|
Ok(Some(Channel::from(params)))
|
||||||
}
|
}
|
||||||
|
@ -88,10 +88,10 @@ pub fn get_clients(connection: &mut Telnet) -> Result<Vec<Client>, String> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn find_client(connection: &mut Telnet, name: &str, strict: bool) -> Result<Option<Client>, String> {
|
pub fn find_client(connection: &mut Telnet, key: &str, value: &str, strict: bool) -> Result<Option<Client>, String> {
|
||||||
match commands::clientlist(connection)? {
|
match commands::clientlist(connection)? {
|
||||||
Response::DataList(parameter_lists) => {
|
Response::DataList(parameter_lists) => {
|
||||||
match parameter::parameter_list_find(¶meter_lists, "client_nickname", name, strict) {
|
match parameter::parameter_list_find(¶meter_lists, key, value, strict) {
|
||||||
Some(params) => {
|
Some(params) => {
|
||||||
Ok(Some(Client::from(params)))
|
Ok(Some(Client::from(params)))
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ fn get_self_clid(connection: &mut Telnet) -> Result<String, String> {
|
||||||
Response::Data(params) => {
|
Response::Data(params) => {
|
||||||
match parameter::parameter_find(¶ms, "clid") {
|
match parameter::parameter_find(¶ms, "clid") {
|
||||||
None => Err(String::from("Could not find clid in models from Teamspeak.")),
|
None => Err(String::from("Could not find clid in models from Teamspeak.")),
|
||||||
Some(param) => Ok(param.value)
|
Some(param) => Ok(param)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => Err(String::from("Received unexpected models from Teamspeak for whoami."))
|
_ => Err(String::from("Received unexpected models from Teamspeak for whoami."))
|
||||||
|
|
|
@ -8,7 +8,8 @@ away
|
||||||
not away
|
not away
|
||||||
back
|
back
|
||||||
message
|
message
|
||||||
message-user"
|
message-user
|
||||||
|
events-move"
|
||||||
|
|
||||||
_ts_control_get_entity() {
|
_ts_control_get_entity() {
|
||||||
entity=$(_ts_control_single_or_dmenu "$(teamspeak-query-lib "$1s")" "$2")
|
entity=$(_ts_control_single_or_dmenu "$(teamspeak-query-lib "$1s")" "$2")
|
||||||
|
@ -97,4 +98,8 @@ case $action in
|
||||||
message=$(_ts_control_get_message "$3")
|
message=$(_ts_control_get_message "$3")
|
||||||
teamspeak-query-lib message --strict-client --client "$user" "$message"
|
teamspeak-query-lib message --strict-client --client "$user" "$message"
|
||||||
;;
|
;;
|
||||||
|
"events-move")
|
||||||
|
teamspeak-query-lib events NotifyClientMoved NotifyClientEnterView \
|
||||||
|
| jq -r --unbuffered '.client.client_nickname + " joined " + .channel.channel_name // "the server"' \
|
||||||
|
| xargs -I{} notify-send "TS3 movement" "{}"
|
||||||
esac
|
esac
|
||||||
|
|
Loading…
Reference in a new issue