Implement SANICK command
Diff
src/client.rs | 58 ++++++++++++++++++++++++++++++++++++++++++++++------------
src/messages.rs | 9 +++++++++
src/server.rs | 20 ++++++++++++++++++++
3 files changed, 67 insertions(+), 20 deletions(-)
@@ -17,6 +17,7 @@
Broadcast, ChannelFetchTopic, ChannelInvite, ChannelJoin, ChannelKickUser, ChannelList,
ChannelMemberList, ChannelMessage, ChannelPart, ChannelUpdateTopic, FetchClientDetails,
ServerDisconnect, ServerFetchMotd, UserKickedFromChannel, UserNickChange,
UserNickChangeInternal,
},
server::Server,
SERVER_NAME,
@@ -221,6 +222,34 @@
}
}
impl Handler<UserNickChangeInternal> for Client {
type Result = ();
#[instrument(parent = &msg.span, skip_all)]
fn handle(&mut self, msg: UserNickChangeInternal, ctx: &mut Self::Context) -> Self::Result {
self.server.do_send(UserNickChange {
client: ctx.address(),
connection: self.connection.clone(),
new_nick: msg.new_nick.clone(),
span: Span::current(),
});
for channel in self.channels.values() {
channel.do_send(UserNickChange {
client: ctx.address(),
connection: self.connection.clone(),
new_nick: msg.new_nick.clone(),
span: Span::current(),
});
}
self.connection.nick = msg.new_nick;
}
}
impl Handler<UserNickChange> for Client {
@@ -280,26 +309,11 @@
}
Command::NICK(new_nick) => {
self.server.do_send(UserNickChange {
client: ctx.address(),
connection: self.connection.clone(),
new_nick: new_nick.clone(),
ctx.notify(UserNickChangeInternal {
old_nick: self.connection.nick.to_string(),
new_nick,
span: Span::current(),
});
for channel in self.channels.values() {
channel.do_send(UserNickChange {
client: ctx.address(),
connection: self.connection.clone(),
new_nick: new_nick.clone(),
span: Span::current(),
});
}
self.connection.nick = new_nick;
}
Command::OPER(_, _) => {}
Command::UserMODE(_, _) => {}
@@ -499,7 +513,13 @@
Command::ISON(_) => {}
Command::SAJOIN(_, _) => {}
Command::SAMODE(_, _, _) => {}
Command::SANICK(_, _) => {}
Command::SANICK(old_nick, new_nick) => {
self.server.do_send(UserNickChangeInternal {
old_nick,
new_nick,
span: Span::current(),
});
}
Command::SAPART(_, _) => {}
Command::SAQUIT(_, _) => {}
Command::NICKSERV(_) => {}
@@ -23,6 +23,15 @@
pub span: Span,
}
#[derive(Message, Clone)]
#[rtype(result = "()")]
pub struct UserNickChangeInternal {
pub old_nick: String,
pub new_nick: String,
pub span: Span,
}
#[derive(Message, Clone)]
#[rtype(result = "()")]
@@ -6,7 +6,7 @@
use futures::{stream::FuturesOrdered, TryFutureExt};
use irc_proto::{Command, Message, Prefix, Response};
use tokio_stream::StreamExt;
use tracing::{instrument, Span};
use tracing::{debug, instrument, warn, Span};
use crate::{
channel::Channel,
@@ -16,6 +16,7 @@
messages::{
Broadcast, ChannelFetchTopic, ChannelJoin, ChannelList, ChannelMemberList,
FetchClientByNick, ServerDisconnect, ServerFetchMotd, UserConnected, UserNickChange,
UserNickChangeInternal,
},
server::response::Motd,
SERVER_NAME,
@@ -26,6 +27,23 @@
pub channels: HashMap<String, Addr<Channel>>,
pub clients: HashMap<Addr<Client>, InitiatedConnection>,
pub config: Config,
}
impl Handler<UserNickChangeInternal> for Server {
type Result = ();
fn handle(&mut self, msg: UserNickChangeInternal, _ctx: &mut Self::Context) -> Self::Result {
let client = self.clients.iter().find(|(_k, v)| v.nick == msg.old_nick);
let Some((client, _)) = client else {
warn!(%msg.old_nick, %msg.new_nick, "User attempted to update nick for unknown user");
return;
};
debug!(%msg.old_nick, %msg.new_nick, "User is updating nick for another user");
client.do_send(msg);
}
}