diff --git a/src/ts6/commands/mod.rs b/src/ts6/commands/mod.rs index f87d99d..c0301a9 100644 --- a/src/ts6/commands/mod.rs +++ b/src/ts6/commands/mod.rs @@ -1,7 +1,7 @@ use std::collections::HashMap; use crate::{ - SENDER, + CONNECTED_USERS, SENDER, messages::Message, sender::IrcResponse, ts6::{ @@ -9,13 +9,14 @@ use crate::{ commands::{ capab::Capab, ping::Ping, privmsg::Privmsg, server::Server, svinfo::Svinfo, uid::Uid, }, + introduce_user, structs::UserId, }, }; use anyhow::anyhow; use async_trait::async_trait; use tokio::{io::BufWriter, net::TcpStream}; -use tracing::debug; +use tracing::{Level, debug, event, info}; mod capab; mod ping; @@ -39,6 +40,8 @@ pub enum Ts6Action { SetInfo(Ts6Info), SendText(IrcResponse), SendMessage(Message), + BroadcastUsers, + LogInfo(String), DoNothing, } @@ -191,6 +194,18 @@ impl Ts6Command { Ts6Action::SendMessage(message) => { message_sender.send(message.clone()).unwrap(); } + Ts6Action::LogInfo(message) => { + info!("{message}"); + } + Ts6Action::BroadcastUsers => { + let my_users = CONNECTED_USERS.lock().await.clone(); + + for user in my_users { + introduce_user(user, &my_sid) + .send(hostname, writer, false) + .await?; + } + } } } diff --git a/src/ts6/commands/svinfo.rs b/src/ts6/commands/svinfo.rs index 017ce43..60614ee 100644 --- a/src/ts6/commands/svinfo.rs +++ b/src/ts6/commands/svinfo.rs @@ -8,6 +8,7 @@ use crate::{ }, }; use async_trait::async_trait; +use tracing::Level; pub struct Svinfo; @@ -36,12 +37,16 @@ impl Ts6Handler for Svinfo { assert_eq!(ts_current, TS_CURRENT); assert_eq!(ts_minimum, TS_MINIMUM); - vec![Ts6Action::SendText(IrcResponse { - sender: None, - command: "SVINFO".to_owned(), - receiver: None, - arguments: vec!["6".to_owned(), "6".to_owned(), "0".to_owned()], - message: format!(":{}", current_time), - })] + vec![ + Ts6Action::SendText(IrcResponse { + sender: None, + command: "SVINFO".to_owned(), + receiver: None, + arguments: vec!["6".to_owned(), "6".to_owned(), "0".to_owned()], + message: format!(":{}", current_time), + }), + Ts6Action::BroadcastUsers, + Ts6Action::LogInfo("server has finished identification".to_string()), + ] } } diff --git a/src/ts6/mod.rs b/src/ts6/mod.rs index cea5d63..c71b6e4 100644 --- a/src/ts6/mod.rs +++ b/src/ts6/mod.rs @@ -21,6 +21,7 @@ use crate::{ commands::Ts6Command, structs::{ServerId, UserId}, }, + user::UserUnwrapped, }; #[derive(Clone, Debug, Default)] @@ -36,6 +37,33 @@ pub struct Ts6 { mod commands; pub mod structs; +fn introduce_user(user: UserUnwrapped, my_sid: &ServerId) -> IrcResponse { + // TODO: refactor this entire thing. we need hostmask and ip and such fully working + IrcResponse { + sender: Some(my_sid.to_string()), + command: "UID".to_string(), + receiver: None, + arguments: vec![ + user.nickname.clone(), + (user.hopcount + 1).to_string(), + user.timestamp + .duration_since(UNIX_EPOCH) + .unwrap() + .as_secs() + .to_string(), + user.usermodes.into(), + format!("~{}", user.username.clone()), + user.ip.to_string(), + user.ip.to_string(), + user.ip.to_string(), + user.user_id.to_string().clone(), + "*".to_owned(), + format!(":{}", user.username.clone()), + ], + message: String::new(), + } +} + impl Ts6 { pub async fn handle_command( &mut self, @@ -113,33 +141,9 @@ impl Ts6 { Message::NetJoinMessage(net_join_message) => { let user = net_join_message.user.clone(); - // TODO: refactor this entire thing. we need hostmask and ip and such fully working - IrcResponse { - sender: Some(hostname.to_string()), - command: "UID".to_string(), - receiver: None, - arguments: vec![ - user.nickname.clone(), - (user.hopcount + 1).to_string(), - user.timestamp - .duration_since(UNIX_EPOCH) - .unwrap() - .as_secs() - .to_string(), - user.usermodes.into(), - format!("~{}", user.username.clone()), - user.ip.to_string(), - user.ip.to_string(), - user.ip.to_string(), - user.user_id.to_string().clone(), - "*".to_owned(), - format!(":{}", user.username.clone()), - ], - message: String::new(), - } - .send(hostname, writer, false) - .await - .unwrap(); + introduce_user(user, my_sid) + .send(hostname, writer, false) + .await?; } Message::PrivMessage(priv_message) => 'priv_message_handler: {