From d3c3cd8292f5bbeb413bc2ac00d08d23010634fe Mon Sep 17 00:00:00 2001 From: user0-07161 Date: Sun, 15 Feb 2026 17:47:10 +0100 Subject: [PATCH] chore: move client-related code into its own directory --- src/{ => client}/commands/cap.rs | 12 +- src/{ => client}/commands/join.rs | 16 +- src/{ => client}/commands/mod.rs | 32 ++-- src/{ => client}/commands/nick.rs | 12 +- src/{ => client}/commands/pass.rs | 16 +- src/{ => client}/commands/ping.rs | 15 +- src/{ => client}/commands/privmsg.rs | 10 +- src/{ => client}/commands/user.rs | 14 +- src/{ => client}/commands/who.rs | 12 +- src/client/mod.rs | 229 +++++++++++++++++++++++++++ src/main.rs | 206 +----------------------- src/ts6/commands/mod.rs | 1 - 12 files changed, 297 insertions(+), 278 deletions(-) rename src/{ => client}/commands/cap.rs (66%) rename src/{ => client}/commands/join.rs (83%) rename src/{ => client}/commands/mod.rs (88%) rename src/{ => client}/commands/nick.rs (83%) rename src/{ => client}/commands/pass.rs (71%) rename src/{ => client}/commands/ping.rs (72%) rename src/{ => client}/commands/privmsg.rs (77%) rename src/{ => client}/commands/user.rs (79%) rename src/{ => client}/commands/who.rs (65%) create mode 100644 src/client/mod.rs diff --git a/src/commands/cap.rs b/src/client/commands/cap.rs similarity index 66% rename from src/commands/cap.rs rename to src/client/commands/cap.rs index cb37f1a..fdccf51 100644 --- a/src/commands/cap.rs +++ b/src/client/commands/cap.rs @@ -1,14 +1,12 @@ use async_trait::async_trait; -use crate::{ - commands::{IrcAction, IrcHandler}, - user::User, -}; +use super::{ClientAction, ClientHandler}; +use crate::user::User; pub struct Cap; #[async_trait] -impl IrcHandler for Cap { +impl ClientHandler for Cap { async fn handle( &self, _arguments: Vec, @@ -17,7 +15,7 @@ impl IrcHandler for Cap { _server_outgoing_password: String, _server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { - vec![IrcAction::DoNothing] + ) -> Vec { + vec![ClientAction::DoNothing] } } diff --git a/src/commands/join.rs b/src/client/commands/join.rs similarity index 83% rename from src/commands/join.rs rename to src/client/commands/join.rs index e42c400..0374707 100644 --- a/src/commands/join.rs +++ b/src/client/commands/join.rs @@ -1,16 +1,12 @@ use async_trait::async_trait; -use crate::{ - JOINED_CHANNELS, - channels::Channel, - commands::{IrcAction, IrcHandler}, - user::User, -}; +use super::{ClientAction, ClientHandler}; +use crate::{JOINED_CHANNELS, channels::Channel, user::User}; pub struct Join; #[async_trait] -impl IrcHandler for Join { +impl ClientHandler for Join { async fn handle( &self, arguments: Vec, @@ -19,7 +15,7 @@ impl IrcHandler for Join { _server_outgoing_password: String, _server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { + ) -> Vec { let mut joined_channels = JOINED_CHANNELS.lock().await; let mut channels = Vec::new(); @@ -31,7 +27,7 @@ impl IrcHandler for Join { } if !authenticated { - return vec![IrcAction::ErrorAuthenticateFirst]; + return vec![ClientAction::ErrorAuthenticateFirst]; } for existing_channel in joined_channels.clone() { @@ -56,6 +52,6 @@ impl IrcHandler for Join { } } - vec![IrcAction::JoinChannels(channels)] + vec![ClientAction::JoinChannels(channels)] } } diff --git a/src/commands/mod.rs b/src/client/commands/mod.rs similarity index 88% rename from src/commands/mod.rs rename to src/client/commands/mod.rs index 1082120..88a1bc8 100644 --- a/src/commands/mod.rs +++ b/src/client/commands/mod.rs @@ -5,13 +5,13 @@ use async_trait::async_trait; use tokio::{io::BufWriter, net::TcpStream, sync::broadcast::Sender}; use tracing::debug; +use super::commands::{ + cap::Cap, join::Join, nick::Nick, pass::Pass, ping::Ping, privmsg::PrivMsg, + user::User as UserHandler, who::Who, +}; use crate::{ SENDER, channels::Channel, - commands::{ - cap::Cap, join::Join, nick::Nick, pass::Pass, ping::Ping, privmsg::PrivMsg, - user::User as UserHandler, who::Who, - }, config::ServerInfo, error_structs::CommandExecError, messages::{ChanJoinMessage, Message}, @@ -29,17 +29,17 @@ mod user; mod who; #[derive(Debug)] -pub struct IrcCommand { +pub struct ClientCommand { command: String, arguments: Vec, } -pub struct IrcMessage { +pub struct ClientMessage { pub sender: String, // TODO: replace with hostmask pub message: String, } -pub enum IrcAction { +pub enum ClientAction { SendText(IrcResponse), SendMessage(Message), JoinChannels(Vec), @@ -55,7 +55,7 @@ pub enum ReturnAction { } #[async_trait] -pub trait IrcHandler: Send + Sync { +pub trait ClientHandler: Send + Sync { async fn handle( &self, command: Vec, @@ -64,12 +64,12 @@ pub trait IrcHandler: Send + Sync { server_outgoing_password: String, server_incoming_passwords: Vec, user_passwords: Vec, - ) -> Vec; + ) -> Vec; } pub struct SendMessage(Option); -impl IrcCommand { +impl ClientCommand { pub async fn new(command_with_arguments: String) -> Self { let mut split_command: Vec<&str> = command_with_arguments .split_whitespace() @@ -114,7 +114,7 @@ impl IrcCommand { user_state: &mut User, config: &ServerInfo, ) -> Result, CommandExecError> { - let mut command_map: HashMap = HashMap::new(); + let mut command_map: HashMap = HashMap::new(); let broadcast_sender = SENDER.lock().await.clone().unwrap(); // Command map is defined here @@ -159,7 +159,7 @@ impl IrcCommand { } } -impl IrcAction { +impl ClientAction { pub async fn execute( &self, writer: &mut BufWriter, @@ -168,11 +168,11 @@ impl IrcAction { sender: Sender, ) -> ReturnAction { match self { - IrcAction::SendText(msg) => { + ClientAction::SendText(msg) => { msg.send(hostname, writer, false).await.unwrap(); } - IrcAction::JoinChannels(channels) => { + ClientAction::JoinChannels(channels) => { for channel in channels { let join_message = ChanJoinMessage { sender: user_state.clone().unwrap_all(), @@ -182,11 +182,11 @@ impl IrcAction { } } - IrcAction::SendMessage(msg) => { + ClientAction::SendMessage(msg) => { sender.send(msg.clone()).unwrap(); } - IrcAction::UpgradeToServerConn => { + ClientAction::UpgradeToServerConn => { return ReturnAction::ServerConn; } diff --git a/src/commands/nick.rs b/src/client/commands/nick.rs similarity index 83% rename from src/commands/nick.rs rename to src/client/commands/nick.rs index 8c5e660..9ca5982 100644 --- a/src/commands/nick.rs +++ b/src/client/commands/nick.rs @@ -1,14 +1,12 @@ use async_trait::async_trait; -use crate::{ - commands::{IrcAction, IrcHandler}, - user::User, -}; +use super::{ClientAction, ClientHandler}; +use crate::user::User; pub struct Nick; #[async_trait] -impl IrcHandler for Nick { +impl ClientHandler for Nick { async fn handle( &self, command: Vec, @@ -17,7 +15,7 @@ impl IrcHandler for Nick { _server_outgoing_password: String, _server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { + ) -> Vec { user_state.nickname = Some({ if command[0].len() > 9 { String::from_utf8( @@ -34,6 +32,6 @@ impl IrcHandler for Nick { } }); - vec![IrcAction::DoNothing] + vec![ClientAction::DoNothing] } } diff --git a/src/commands/pass.rs b/src/client/commands/pass.rs similarity index 71% rename from src/commands/pass.rs rename to src/client/commands/pass.rs index 480d7e7..787a880 100644 --- a/src/commands/pass.rs +++ b/src/client/commands/pass.rs @@ -1,14 +1,12 @@ use async_trait::async_trait; -use crate::{ - commands::{IrcAction, IrcHandler}, - user::User, -}; +use super::{ClientAction, ClientHandler}; +use crate::user::User; pub struct Pass; #[async_trait] -impl IrcHandler for Pass { +impl ClientHandler for Pass { async fn handle( &self, command: Vec, @@ -17,22 +15,22 @@ impl IrcHandler for Pass { server_outgoing_password: String, server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { + ) -> Vec { // XXX if server_incoming_passwords.contains(&command[0]) { vec![ - IrcAction::SendText(crate::sender::IrcResponse { + ClientAction::SendText(crate::sender::IrcResponse { sender: None, command: "PASS".to_owned(), receiver: None, arguments: Vec::new(), message: server_outgoing_password.clone(), }), - IrcAction::UpgradeToServerConn, + ClientAction::UpgradeToServerConn, ] } else { - vec![IrcAction::DoNothing] + vec![ClientAction::DoNothing] } } } diff --git a/src/commands/ping.rs b/src/client/commands/ping.rs similarity index 72% rename from src/commands/ping.rs rename to src/client/commands/ping.rs index 6caf357..b65b09c 100644 --- a/src/commands/ping.rs +++ b/src/client/commands/ping.rs @@ -1,15 +1,12 @@ use async_trait::async_trait; -use crate::{ - commands::{IrcAction, IrcHandler}, - sender::IrcResponse, - user::User, -}; +use super::{ClientAction, ClientHandler}; +use crate::{sender::IrcResponse, user::User}; pub struct Ping; #[async_trait] -impl IrcHandler for Ping { +impl ClientHandler for Ping { async fn handle( &self, command: Vec, @@ -18,9 +15,9 @@ impl IrcHandler for Ping { _server_outgoing_password: String, _server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { + ) -> Vec { if authenticated { - vec![IrcAction::SendText(IrcResponse { + vec![ClientAction::SendText(IrcResponse { sender: None, command: "PONG".into(), arguments: Vec::new(), @@ -28,7 +25,7 @@ impl IrcHandler for Ping { message: format!(":{}", command[0].clone()), })] } else { - vec![IrcAction::DoNothing] + vec![ClientAction::DoNothing] } } } diff --git a/src/commands/privmsg.rs b/src/client/commands/privmsg.rs similarity index 77% rename from src/commands/privmsg.rs rename to src/client/commands/privmsg.rs index 9a3ed2c..7c23eef 100644 --- a/src/commands/privmsg.rs +++ b/src/client/commands/privmsg.rs @@ -1,7 +1,7 @@ use async_trait::async_trait; +use super::{ClientAction, ClientHandler}; use crate::{ - commands::{IrcAction, IrcHandler}, messages::{Message, PrivMessage, Receiver}, user::User, }; @@ -9,7 +9,7 @@ use crate::{ pub struct PrivMsg; #[async_trait] -impl IrcHandler for PrivMsg { +impl ClientHandler for PrivMsg { async fn handle( &self, command: Vec, @@ -18,9 +18,9 @@ impl IrcHandler for PrivMsg { _server_outgoing_password: String, _server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { + ) -> Vec { if !authenticated { - return vec![IrcAction::ErrorAuthenticateFirst]; + return vec![ClientAction::ErrorAuthenticateFirst]; } let receiver = if command[0].clone().starts_with("#") { @@ -35,6 +35,6 @@ impl IrcHandler for PrivMsg { text: command[1].clone(), }; - vec![IrcAction::SendMessage(Message::PrivMessage(message))] + vec![ClientAction::SendMessage(Message::PrivMessage(message))] } } diff --git a/src/commands/user.rs b/src/client/commands/user.rs similarity index 79% rename from src/commands/user.rs rename to src/client/commands/user.rs index dcfdabc..4b302c3 100644 --- a/src/commands/user.rs +++ b/src/client/commands/user.rs @@ -1,14 +1,12 @@ use async_trait::async_trait; -use crate::{ - commands::{IrcAction, IrcHandler}, - user::User as UserState, -}; +use super::{ClientAction, ClientHandler}; +use crate::user::User as UserState; pub struct User; #[async_trait] -impl IrcHandler for User { +impl ClientHandler for User { async fn handle( &self, command: Vec, @@ -17,9 +15,9 @@ impl IrcHandler for User { _server_outgoing_password: String, _server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { + ) -> Vec { if command.len() < 4 { - return vec![IrcAction::DoNothing]; // XXX: return an error + return vec![ClientAction::DoNothing]; // XXX: return an error } // oh my god this is a mess @@ -40,6 +38,6 @@ impl IrcHandler for User { }); user_state.realname = Some(command[3].clone()); - vec![IrcAction::DoNothing] + vec![ClientAction::DoNothing] } } diff --git a/src/commands/who.rs b/src/client/commands/who.rs similarity index 65% rename from src/commands/who.rs rename to src/client/commands/who.rs index 0d57f47..a4b5511 100644 --- a/src/commands/who.rs +++ b/src/client/commands/who.rs @@ -1,14 +1,12 @@ use async_trait::async_trait; -use crate::{ - commands::{IrcAction, IrcHandler}, - user::User, -}; +use super::{ClientAction, ClientHandler}; +use crate::user::User; pub struct Who; #[async_trait] -impl IrcHandler for Who { +impl ClientHandler for Who { async fn handle( &self, _arguments: Vec, @@ -17,7 +15,7 @@ impl IrcHandler for Who { _server_outgoing_password: String, _server_incoming_passwords: Vec, _user_passwords: Vec, - ) -> Vec { - vec![IrcAction::DoNothing] // TODO + ) -> Vec { + vec![ClientAction::DoNothing] // TODO } } diff --git a/src/client/mod.rs b/src/client/mod.rs new file mode 100644 index 0000000..c8e6f27 --- /dev/null +++ b/src/client/mod.rs @@ -0,0 +1,229 @@ +use std::{ + net::TcpStream, + time::{Duration, SystemTime}, +}; + +use crate::{ + CONNECTED_USERS, JOINED_CHANNELS, SENDER, TcpListenerResult, + config::ServerInfo, + error_structs::{self, ListenerError}, + login::send_motd, + messages::{Message, NetJoinMessage, Receiver as MsgReceiver}, + sender::{IrcResponse, IrcResponseCodes}, + ts6::structs::{ServerId, UserId}, + user::User, + userid_gen, +}; + +use tokio::{ + io::{AsyncBufReadExt, BufReader as TokioBufReader, BufWriter as TokioBufWriter}, + net::TcpStream as TokioTcpStream, + spawn, + sync::{ + Mutex, + broadcast::{self, Receiver, Sender}, + }, + time::sleep, +}; +use tracing::debug; + +mod commands; + +#[derive(Clone, Debug, Default)] +pub struct Client {} + +impl Client { + pub async fn tcp_listener( + &self, + stream: &TcpStream, + mut user_state: User, + info: &ServerInfo, + reader: &mut TokioBufReader, + our_sid: ServerId, + ) -> Result { + let mut buffer = String::new(); + + let mut writer = TokioBufWriter::new(TokioTcpStream::from_std(stream.try_clone()?)?); + + match reader.read_line(&mut buffer).await { + Ok(0) => return Err(ListenerError::ConnectionError), + Ok(_) => {} + + Err(_) => { + let mut conneted_users = CONNECTED_USERS.lock().await; + let _ = conneted_users.remove(&user_state.clone().unwrap_all()); + + return Err(ListenerError::ConnectionError); + } + } + + let command = commands::ClientCommand::new(buffer.clone()).await; + match command + .execute(&mut writer, &info.server_hostname, &mut user_state, info) + .await + { + Ok(return_actions) => { + for return_action in return_actions { + match return_action { + commands::ReturnAction::ServerConn => { + return Ok(TcpListenerResult::ServerConnectionInit); + } + + _ => {} + } + } + } + Err(error) => match error { + error_structs::CommandExecError::NonexistantCommand => { + let error_string = format!("error processing your command: {error:#?}\n"); + let error = IrcResponseCodes::UnknownCommand; + + error + .into_irc_response("*".into(), error_string.into()) + .send(&info.server_hostname, &mut writer, true) + .await + .unwrap(); + } + }, + } + + if !user_state.identified && user_state.is_populated_without_uid() { + let id = userid_gen::increase_user_id() + .await + .unwrap() + .iter() + .map(|x| x.to_string()) + .collect::>() + .join(""); + let user_id = format!("{our_sid}{id}"); + + user_state.identified = true; + user_state.user_id = Some(UserId::try_from(user_id).unwrap()); // XXX: error handling + user_state.timestamp = Some(SystemTime::now()); + + send_motd(info.clone(), user_state.clone(), &mut writer).await?; + + let broadcast_sender = SENDER.lock().await.clone().unwrap(); + + broadcast_sender + .send(Message::NetJoinMessage(NetJoinMessage { + user: user_state.clone().unwrap_all(), + server_id: our_sid.clone(), + })) + .unwrap(); + + CONNECTED_USERS + .lock() + .await + .insert(user_state.clone().unwrap_all()); + } + + Ok(TcpListenerResult::UpdatedUser(user_state)) + } + + pub async fn message_listener( + &self, + user_wrapped: &User, + receiver: &mut Receiver, + writer: &mut TokioBufWriter, + hostname: &str, + ) -> Result<(), ListenerError> { + if !user_wrapped.is_populated() { + sleep(Duration::from_millis(250)).await; // avoid immediate returns b'cuz they result in high + // cpu usage + return Err(ListenerError::UserIsUnidentified); + } + + let user = user_wrapped.clone().unwrap_all(); + let message: Message = receiver.recv().await.unwrap(); + let joined_channels = JOINED_CHANNELS.lock().await; + + let mut channel_name: Option = None; + + debug!("new message in the message stream: {message:?}"); + + match message { + Message::PrivMessage(message) => { + for channel in joined_channels.clone() { + if let MsgReceiver::ChannelName(channelname) = message.clone().receiver + && channelname == channel.name + && channel.joined_users.contains(user_wrapped) + { + channel_name = Some(channel.name.clone()); + } + } + + dbg!(&message); + + if match message.clone().receiver { + MsgReceiver::UserId(userid) => { + debug!("{userid} ?= {}", user.user_id); + if userid == user.user_id { true } else { false } + } + + MsgReceiver::Username(username) => { + if username.to_lowercase() == user.username.to_lowercase() { + true + } else { + false + } + } + + _ => false, + } { + IrcResponse { + sender: Some(message.sender.hostmask()), + command: "PRIVMSG".into(), + arguments: Vec::new(), + message: message.text, + receiver: Some(user.username.clone()), + } + .send("", writer, true) + .await?; + } else if let Some(channel_name) = channel_name { + if message.sender != user { + IrcResponse { + sender: Some(message.sender.hostmask()), + command: "PRIVMSG".into(), + arguments: Vec::new(), + message: message.text, + receiver: Some(channel_name), + } + .send("", writer, true) + .await?; + } + } + } + + Message::ChanJoinMessage(message) => { + if message.channel.joined_users.contains(user_wrapped) || message.sender == user { + let channel = message.channel.clone(); + + IrcResponse { + sender: Some(message.sender.hostmask().clone()), + command: "JOIN".into(), + arguments: Vec::new(), + message: message.channel.name.clone(), + receiver: None, + } + .send("", writer, true) + .await?; + + channel + .send_topic(user_wrapped.clone(), writer, hostname) + .await + .unwrap(); + + channel + .names_list_send(user_wrapped.clone(), &channel, writer, hostname) + .await + .unwrap(); + } + } + + Message::NetJoinMessage(_) => {} // we don't care about these here :) + } + + Ok(()) + } +} diff --git a/src/main.rs b/src/main.rs index 0dcdecb..5be212c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,6 +23,7 @@ use tracing::{debug, instrument}; use crate::{ channels::Channel, + client::Client, config::ServerInfo, error_structs::{HandlerError, ListenerError}, logging::LogLevel, @@ -37,7 +38,7 @@ use crate::{ }; mod channels; -mod commands; +mod client; mod config; mod error_structs; mod logging; @@ -93,9 +94,7 @@ async fn main() -> Result<(), AnyhowError> { let tx_thread = tx.clone(); let info = info.clone(); - spawn(handle_connection( - stream, info, /*&mut rx_thread,*/ tx_thread, - )); + spawn(handle_connection(stream, info, tx_thread)); } Ok(()) @@ -117,12 +116,13 @@ async fn handle_connection( let hostname = info.server_hostname.clone(); - // TODO: generate randomally and allow overriding from config + // TODO: generate randomly and allow overriding from config let my_server_id = ServerId::try_from("000".to_owned()).unwrap(); + let client_status = Client::default(); loop { tokio::select! { - result = tcp_listener(&stream_tcp, state.clone(), &info, &mut tcp_reader, my_server_id.clone()) => { + result = client_status.tcp_listener(&stream_tcp, state.clone(), &info, &mut tcp_reader, my_server_id.clone()) => { match result { Ok(tcp_listener_result) => { match tcp_listener_result { @@ -141,7 +141,7 @@ async fn handle_connection( } } }, - result = message_listener(&state, &mut message_receiver, &mut tcp_writer, &hostname) => { + result = client_status.message_listener(&state, &mut message_receiver, &mut tcp_writer, &hostname) => { match result { Ok(_) => {}, Err(err) => { @@ -191,198 +191,6 @@ async fn handle_connection( Ok(()) } -async fn tcp_listener( - stream: &TcpStream, - mut user_state: User, - info: &ServerInfo, - reader: &mut TokioBufReader, - our_sid: ServerId, -) -> Result { - let mut buffer = String::new(); - - let mut writer = TokioBufWriter::new(TokioTcpStream::from_std(stream.try_clone()?)?); - - match reader.read_line(&mut buffer).await { - Ok(0) => return Err(ListenerError::ConnectionError), - Ok(_) => {} - - Err(_) => { - let mut conneted_users = CONNECTED_USERS.lock().await; - let _ = conneted_users.remove(&user_state.clone().unwrap_all()); - - return Err(ListenerError::ConnectionError); - } - } - - let command = commands::IrcCommand::new(buffer.clone()).await; - match command - .execute(&mut writer, &info.server_hostname, &mut user_state, info) - .await - { - Ok(return_actions) => { - for return_action in return_actions { - match return_action { - commands::ReturnAction::ServerConn => { - return Ok(TcpListenerResult::ServerConnectionInit); - } - - _ => {} - } - } - } - Err(error) => match error { - error_structs::CommandExecError::NonexistantCommand => { - let error_string = format!("error processing your command: {error:#?}\n"); - let error = IrcResponseCodes::UnknownCommand; - - error - .into_irc_response("*".into(), error_string.into()) - .send(&info.server_hostname, &mut writer, true) - .await - .unwrap(); - } - }, - } - - if !user_state.identified && user_state.is_populated_without_uid() { - let id = userid_gen::increase_user_id() - .await - .unwrap() - .iter() - .map(|x| x.to_string()) - .collect::>() - .join(""); - let user_id = format!("{our_sid}{id}"); - - user_state.identified = true; - user_state.user_id = Some(UserId::try_from(user_id).unwrap()); // XXX: error handling - user_state.timestamp = Some(SystemTime::now()); - - send_motd(info.clone(), user_state.clone(), &mut writer).await?; - - let broadcast_sender = SENDER.lock().await.clone().unwrap(); - - broadcast_sender - .send(Message::NetJoinMessage(NetJoinMessage { - user: user_state.clone().unwrap_all(), - server_id: our_sid.clone(), - })) - .unwrap(); - - CONNECTED_USERS - .lock() - .await - .insert(user_state.clone().unwrap_all()); - } - - Ok(TcpListenerResult::UpdatedUser(user_state)) -} - -async fn message_listener( - user_wrapped: &User, - receiver: &mut Receiver, - writer: &mut TokioBufWriter, - hostname: &str, -) -> Result<(), ListenerError> { - if !user_wrapped.is_populated() { - sleep(Duration::from_millis(250)).await; // avoid immediate returns b'cuz they result in high - // cpu usage - return Err(ListenerError::UserIsUnidentified); - } - - let user = user_wrapped.clone().unwrap_all(); - let message: Message = receiver.recv().await.unwrap(); - let joined_channels = JOINED_CHANNELS.lock().await; - - let mut channel_name: Option = None; - - debug!("new message in the message stream: {message:?}"); - - match message { - Message::PrivMessage(message) => { - for channel in joined_channels.clone() { - if let MsgReceiver::ChannelName(channelname) = message.clone().receiver - && channelname == channel.name - && channel.joined_users.contains(user_wrapped) - { - channel_name = Some(channel.name.clone()); - } - } - - dbg!(&message); - - if match message.clone().receiver { - MsgReceiver::UserId(userid) => { - debug!("{userid} ?= {}", user.user_id); - if userid == user.user_id { true } else { false } - } - - MsgReceiver::Username(username) => { - if username.to_lowercase() == user.username.to_lowercase() { - true - } else { - false - } - } - - _ => false, - } { - IrcResponse { - sender: Some(message.sender.hostmask()), - command: "PRIVMSG".into(), - arguments: Vec::new(), - message: message.text, - receiver: Some(user.username.clone()), - } - .send("", writer, true) - .await?; - } else if let Some(channel_name) = channel_name { - if message.sender != user { - IrcResponse { - sender: Some(message.sender.hostmask()), - command: "PRIVMSG".into(), - arguments: Vec::new(), - message: message.text, - receiver: Some(channel_name), - } - .send("", writer, true) - .await?; - } - } - } - - Message::ChanJoinMessage(message) => { - if message.channel.joined_users.contains(user_wrapped) || message.sender == user { - let channel = message.channel.clone(); - - IrcResponse { - sender: Some(message.sender.hostmask().clone()), - command: "JOIN".into(), - arguments: Vec::new(), - message: message.channel.name.clone(), - receiver: None, - } - .send("", writer, true) - .await?; - - channel - .send_topic(user_wrapped.clone(), writer, hostname) - .await - .unwrap(); - - channel - .names_list_send(user_wrapped.clone(), &channel, writer, hostname) - .await - .unwrap(); - } - } - - Message::NetJoinMessage(_) => {} // we don't care about these here :) - } - - Ok(()) -} - #[cfg(test)] mod tests { use crate::userid_gen; diff --git a/src/ts6/commands/mod.rs b/src/ts6/commands/mod.rs index cd2321b..c6b61fa 100644 --- a/src/ts6/commands/mod.rs +++ b/src/ts6/commands/mod.rs @@ -2,7 +2,6 @@ use std::collections::HashMap; use crate::{ SENDER, - commands::IrcMessage, messages::Message, sender::IrcResponse, ts6::{