From 192341583d34dec0ba3c9999eea22a93947ce052 Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Tue, 30 Jan 2024 02:57:28 +0000 Subject: [PATCH] Implement KILL --- src/client.rs | 33 ++++++++++++++++++++++++--------- src/messages.rs | 9 +++++++++ src/server.rs | 16 +++++++++++++++- 3 files changed, 48 insertions(+), 10 deletions(-) diff --git a/src/client.rs b/src/client.rs index d452aa0..9de2125 100644 --- a/src/client.rs +++ b/src/client.rs @@ -24,7 +24,7 @@ use crate::{ Broadcast, ChannelFetchTopic, ChannelFetchWhoList, ChannelInvite, ChannelJoin, ChannelKickUser, ChannelList, ChannelMemberList, ChannelMessage, ChannelPart, ChannelSetMode, ChannelUpdateTopic, ClientAway, ConnectedChannels, FetchClientDetails, - FetchUserPermission, FetchWhoList, FetchWhois, MessageKind, PrivateMessage, + FetchUserPermission, FetchWhoList, FetchWhois, KillUser, MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect, ServerFetchMotd, ServerListUsers, UserKickedFromChannel, UserNickChange, UserNickChangeInternal, Wallops, }, @@ -246,7 +246,10 @@ impl Actor for Client { command: Command::ERROR(if self.graceful_shutdown { String::new() } else { - message.unwrap_or_else(|| "Ungraceful shutdown".to_string()) + format!( + "Closing Link: {}", + message.as_deref().unwrap_or("Ungraceful shutdown") + ) }), }); } @@ -373,6 +376,17 @@ impl Handler for Client { } } +/// Disconnects the current user from the server as a result of the `KILL` command. +impl Handler for Client { + type Result = (); + + #[instrument(parent = & msg.span, skip_all)] + fn handle(&mut self, msg: KillUser, ctx: &mut Self::Context) -> Self::Result { + self.server_leave_reason = Some(format!("Killed ({} ({}))", msg.killer, msg.comment)); + ctx.stop(); + } +} + /// A self-message from the Client's [`StreamHandler`] implementation when the user /// sends a join command out. /// @@ -859,7 +873,14 @@ impl StreamHandler> for Client { }); } Command::WHOWAS(_, _, _) => {} - Command::KILL(_, _) => {} + Command::KILL(nick, comment) => { + self.server.do_send(KillUser { + span: Span::current(), + killer: self.connection.nick.to_string(), + comment, + killed: nick, + }); + } Command::PING(v, _) => { self.writer.write(Message { tags: None, @@ -899,12 +920,6 @@ impl StreamHandler> for Client { } Command::SAPART(_, _) => {} Command::SAQUIT(_, _) => {} - Command::NICKSERV(_) => {} - Command::CHANSERV(_) => {} - Command::OPERSERV(_) => {} - Command::BOTSERV(_) => {} - Command::HOSTSERV(_) => {} - Command::MEMOSERV(_) => {} Command::AUTHENTICATE(_) => { self.writer.write( SaslAlreadyAuthenticated(self.connection.nick.to_string()).into_message(), diff --git a/src/messages.rs b/src/messages.rs index 6a14bf0..8265e2e 100644 --- a/src/messages.rs +++ b/src/messages.rs @@ -28,6 +28,15 @@ pub struct ServerDisconnect { pub span: Span, } +#[derive(Message, Clone)] +#[rtype(result = "()")] +pub struct KillUser { + pub span: Span, + pub killer: String, + pub comment: String, + pub killed: String, +} + /// Internal event to update a user's nick. #[derive(Message, Clone)] #[rtype(result = "()")] diff --git a/src/server.rs b/src/server.rs index cc0ec2f..7b78b19 100644 --- a/src/server.rs +++ b/src/server.rs @@ -26,7 +26,7 @@ use crate::{ messages::{ Broadcast, ChannelFetchTopic, ChannelFetchWhoList, ChannelJoin, ChannelList, ChannelMemberList, ClientAway, ConnectedChannels, FetchClientByNick, FetchWhoList, - FetchWhois, MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect, + FetchWhois, KillUser, MessageKind, PrivateMessage, ServerAdminInfo, ServerDisconnect, ServerFetchMotd, ServerListUsers, UserConnected, UserNickChange, UserNickChangeInternal, Wallops, }, @@ -238,6 +238,20 @@ impl Handler for Server { } } +/// Looks up a user to disconnect and sends the disconnect notification. +impl Handler for Server { + type Result = (); + + #[instrument(parent = &msg.span, skip_all)] + fn handle(&mut self, msg: KillUser, _ctx: &mut Self::Context) -> Self::Result { + for (handle, user) in &self.clients { + if user.nick == msg.killed { + handle.do_send(msg.clone()); + } + } + } +} + impl Handler for Server { type Result = (); -- libgit2 1.7.2