use anyhow::{bail, Result};
use futures::prelude::*;
use structopt::StructOpt;
use tokio::time::{self, Duration};
use tsclientlib::data::{self, Channel, Client};
use tsclientlib::prelude::*;
use tsclientlib::{ChannelId, Connection, DisconnectOptions, Identity, StreamItem};
#[derive(StructOpt, Debug)]
#[structopt(author, about)]
struct Args {
#[structopt(short = "a", long, default_value = "localhost")]
address: String,
#[structopt(short = "v", long, parse(from_occurrences))]
verbose: u8,
}
fn print_channels(clients: &[&Client], channels: &[&Channel], parent: ChannelId, depth: usize) {
let indention = " ".repeat(depth);
for channel in channels {
if channel.parent == parent {
println!("{}- {}", indention, channel.name);
for client in clients {
if client.channel == channel.id {
println!("{} {}", indention, client.name);
}
}
print_channels(clients, channels, channel.id, depth + 1);
}
}
}
fn print_channel_tree(con: &data::Connection) {
let mut channels: Vec<_> = con.channels.values().collect();
let mut clients: Vec<_> = con.clients.values().collect();
channels.sort_by_key(|ch| ch.order.0);
clients.sort_by_key(|c| c.talk_power);
println!("{}", con.server.name);
print_channels(&clients, &channels, ChannelId(0), 0);
}
#[tokio::main]
async fn main() -> Result<()> { real_main().await }
async fn real_main() -> Result<()> {
let args = Args::from_args();
let con_config = Connection::build(args.address)
.log_commands(args.verbose >= 1)
.log_packets(args.verbose >= 2)
.log_udp_packets(args.verbose >= 3);
let id = Identity::new_from_str(
"MG0DAgeAAgEgAiAIXJBlj1hQbaH0Eq0DuLlCmH8bl+veTAO2+\
k9EQjEYSgIgNnImcmKo7ls5mExb6skfK2Tw+u54aeDr0OP1ITs\
C/50CIA8M5nmDBnmDM/gZ//4AAAAAAAAAAAAAAAAAAAAZRzOI").unwrap();
let con_config = con_config.identity(id);
let mut con = con_config.connect()?;
let r = con
.events()
.try_filter(|e| future::ready(matches!(e, StreamItem::BookEvents(_))))
.next()
.await;
if let Some(r) = r {
r?;
}
con.get_state().unwrap().server.set_subscribed(true).send(&mut con)?;
let mut events = con.events().try_filter(|_| future::ready(false));
tokio::select! {
_ = time::sleep(Duration::from_secs(1)) => {}
_ = events.next() => {
bail!("Disconnected");
}
};
drop(events);
print_channel_tree(con.get_state().unwrap());
{
let state = con.get_state().unwrap();
let name = state.clients[&state.own_client].name.clone();
state
.client_update()
.set_input_muted(true)
.set_name(&format!("{}1", name))
.send(&mut con)?;
}
let mut events = con.events().try_filter(|_| future::ready(false));
tokio::select! {
_ = time::sleep(Duration::from_secs(3)) => {}
_ = events.next() => {
bail!("Disconnected");
}
};
drop(events);
con.disconnect(DisconnectOptions::new())?;
con.events().for_each(|_| future::ready(())).await;
Ok(())
}