feat: introduce users who are already logged in on server connection-time
All checks were successful
build / test-alpine (push) Successful in 26s
build / test-debian (push) Successful in 52s

apparently ircd-hybrid uses the sid instead of the hostname in UID
messages
This commit is contained in:
user0-07161 2026-02-15 20:15:28 +01:00
parent c736663ccc
commit d32ec1d13c
3 changed files with 60 additions and 36 deletions

View file

@ -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?;
}
}
}
}

View file

@ -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 {
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()),
]
}
}

View file

@ -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(),
}
introduce_user(user, my_sid)
.send(hostname, writer, false)
.await
.unwrap();
.await?;
}
Message::PrivMessage(priv_message) => 'priv_message_handler: {