mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-04-28 03:00:18 -04:00
bin/ircd: implement CAP command
This commit is contained in:
@@ -31,9 +31,11 @@ pub struct IrcServerConnection {
|
||||
is_nick_init: bool,
|
||||
is_user_init: bool,
|
||||
is_registered: bool,
|
||||
is_cap_end: bool,
|
||||
nickname: String,
|
||||
auto_channels: Vec<String>,
|
||||
pub configured_chans: FxHashMap<String, ChannelInfo>,
|
||||
capabilities: FxHashMap<String, bool>,
|
||||
// p2p
|
||||
p2p: P2pPtr,
|
||||
senders: SubscriberPtr<Privmsg>,
|
||||
@@ -53,6 +55,8 @@ impl IrcServerConnection {
|
||||
senders: SubscriberPtr<Privmsg>,
|
||||
subscriber_id: u64,
|
||||
) -> Self {
|
||||
let mut capabilities = FxHashMap::default();
|
||||
capabilities.insert("no-history".to_string(), false);
|
||||
Self {
|
||||
write_stream,
|
||||
peer_address,
|
||||
@@ -61,9 +65,11 @@ impl IrcServerConnection {
|
||||
is_nick_init: false,
|
||||
is_user_init: false,
|
||||
is_registered: false,
|
||||
is_cap_end: false,
|
||||
nickname: "anon".to_string(),
|
||||
auto_channels,
|
||||
configured_chans,
|
||||
capabilities,
|
||||
p2p,
|
||||
senders,
|
||||
subscriber_id,
|
||||
@@ -199,7 +205,78 @@ impl IrcServerConnection {
|
||||
|
||||
self.on_receive_privmsg(&message, target).await?;
|
||||
}
|
||||
"CAP" => {}
|
||||
"CAP" => {
|
||||
let subcommand = tokens.next().ok_or(Error::MalformedPacket)?.to_uppercase();
|
||||
|
||||
let capabilities_keys: Vec<String> = self.capabilities.keys().cloned().collect();
|
||||
|
||||
if subcommand == "LS" {
|
||||
let cap_ls_reply = format!(
|
||||
":{}!anon@dark.fi CAP * LS :{}\r\n",
|
||||
self.nickname,
|
||||
capabilities_keys.join(" ")
|
||||
);
|
||||
self.reply(&cap_ls_reply).await?;
|
||||
}
|
||||
|
||||
if subcommand == "REQ" {
|
||||
let substr_idx = line.find(':').ok_or(Error::MalformedPacket)?;
|
||||
|
||||
if substr_idx >= line.len() {
|
||||
return Err(Error::MalformedPacket)
|
||||
}
|
||||
|
||||
let cap: Vec<&str> = line[substr_idx + 1..].split(" ").collect();
|
||||
|
||||
let mut ack_list = vec![];
|
||||
let mut nak_list = vec![];
|
||||
|
||||
for c in cap {
|
||||
if self.capabilities.contains_key(c) {
|
||||
self.capabilities.insert(c.to_string(), true);
|
||||
ack_list.push(c);
|
||||
} else {
|
||||
nak_list.push(c);
|
||||
}
|
||||
}
|
||||
|
||||
let cap_ack_reply = format!(
|
||||
":{}!anon@dark.fi CAP * ACK :{}\r\n",
|
||||
self.nickname,
|
||||
ack_list.join(" ")
|
||||
);
|
||||
|
||||
let cap_nak_reply = format!(
|
||||
":{}!anon@dark.fi CAP * NAK :{}\r\n",
|
||||
self.nickname,
|
||||
nak_list.join(" ")
|
||||
);
|
||||
|
||||
self.reply(&cap_ack_reply).await?;
|
||||
self.reply(&cap_nak_reply).await?;
|
||||
}
|
||||
|
||||
if subcommand == "LIST" {
|
||||
let enabled_capabilities: Vec<String> = self
|
||||
.capabilities
|
||||
.clone()
|
||||
.into_iter()
|
||||
.filter(|(_, v)| *v)
|
||||
.map(|(k, _)| k)
|
||||
.collect();
|
||||
|
||||
let cap_list_reply = format!(
|
||||
":{}!anon@dark.fi CAP * LIST :{}\r\n",
|
||||
self.nickname,
|
||||
enabled_capabilities.join(" ")
|
||||
);
|
||||
self.reply(&cap_list_reply).await?;
|
||||
}
|
||||
|
||||
if subcommand == "END" {
|
||||
self.is_cap_end = true;
|
||||
}
|
||||
}
|
||||
"QUIT" => {
|
||||
// Close the connection
|
||||
return Err(Error::NetworkServiceStopped)
|
||||
@@ -210,7 +287,7 @@ impl IrcServerConnection {
|
||||
}
|
||||
|
||||
// on registration
|
||||
if !self.is_registered && self.is_nick_init && self.is_user_init {
|
||||
if !self.is_registered && self.is_cap_end && self.is_nick_init && self.is_user_init {
|
||||
debug!("Initializing peer connection");
|
||||
let register_reply = format!(":darkfi 001 {} :Let there be dark\r\n", self.nickname);
|
||||
self.reply(®ister_reply).await?;
|
||||
@@ -221,13 +298,13 @@ impl IrcServerConnection {
|
||||
}
|
||||
|
||||
// Send dm messages in buffer
|
||||
for msg in self.privmsgs_buffer.lock().await.to_vec() {
|
||||
if msg.target == self.nickname || msg.nickname == self.nickname {
|
||||
self.senders.notify_by_id(msg, self.subscriber_id).await;
|
||||
if !self.capabilities.get("no-history").unwrap() {
|
||||
for msg in self.privmsgs_buffer.lock().await.to_vec() {
|
||||
if msg.target == self.nickname || msg.nickname == self.nickname {
|
||||
self.senders.notify_by_id(msg, self.subscriber_id).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// send names command
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@@ -282,7 +359,6 @@ impl IrcServerConnection {
|
||||
(*self.seen_msg_ids.lock().await).push(random_id);
|
||||
(*self.privmsgs_buffer.lock().await).push(protocol_msg.clone())
|
||||
}
|
||||
|
||||
self.senders.notify_with_exclude(protocol_msg.clone(), &[self.subscriber_id]).await;
|
||||
|
||||
debug!(target: "ircd", "PRIVMSG to be sent: {:?}", protocol_msg);
|
||||
@@ -312,9 +388,11 @@ impl IrcServerConnection {
|
||||
}
|
||||
|
||||
// Send messages in buffer
|
||||
for msg in self.privmsgs_buffer.lock().await.to_vec() {
|
||||
if msg.target == chan {
|
||||
self.senders.notify_by_id(msg, self.subscriber_id).await;
|
||||
if !self.capabilities.get("no-history").unwrap() {
|
||||
for msg in self.privmsgs_buffer.lock().await.to_vec() {
|
||||
if msg.target == chan {
|
||||
self.senders.notify_by_id(msg, self.subscriber_id).await;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -355,7 +433,10 @@ impl IrcServerConnection {
|
||||
return Ok(())
|
||||
}
|
||||
|
||||
if self.is_nick_init && (self.nickname == msg.target || self.nickname == msg.nickname) {
|
||||
if self.is_cap_end &&
|
||||
self.is_nick_init &&
|
||||
(self.nickname == msg.target || self.nickname == msg.nickname)
|
||||
{
|
||||
self.reply(&msg.to_irc_msg()).await?;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user