feat: introduce users who are already logged in on server connection-time
Some checks failed
build / test-alpine (push) Successful in 49s
build / test-debian (push) Has been cancelled

This commit is contained in:
user0-07161 2026-02-15 20:15:28 +01:00
parent c736663ccc
commit 8d28c00cbd
3 changed files with 60 additions and 36 deletions

View file

@ -1,7 +1,7 @@
use std::collections::HashMap; use std::collections::HashMap;
use crate::{ use crate::{
SENDER, CONNECTED_USERS, SENDER,
messages::Message, messages::Message,
sender::IrcResponse, sender::IrcResponse,
ts6::{ ts6::{
@ -9,13 +9,14 @@ use crate::{
commands::{ commands::{
capab::Capab, ping::Ping, privmsg::Privmsg, server::Server, svinfo::Svinfo, uid::Uid, capab::Capab, ping::Ping, privmsg::Privmsg, server::Server, svinfo::Svinfo, uid::Uid,
}, },
introduce_user,
structs::UserId, structs::UserId,
}, },
}; };
use anyhow::anyhow; use anyhow::anyhow;
use async_trait::async_trait; use async_trait::async_trait;
use tokio::{io::BufWriter, net::TcpStream}; use tokio::{io::BufWriter, net::TcpStream};
use tracing::debug; use tracing::{Level, debug, event, info};
mod capab; mod capab;
mod ping; mod ping;
@ -39,6 +40,8 @@ pub enum Ts6Action {
SetInfo(Ts6Info), SetInfo(Ts6Info),
SendText(IrcResponse), SendText(IrcResponse),
SendMessage(Message), SendMessage(Message),
BroadcastUsers,
LogInfo(String),
DoNothing, DoNothing,
} }
@ -191,6 +194,18 @@ impl Ts6Command {
Ts6Action::SendMessage(message) => { Ts6Action::SendMessage(message) => {
message_sender.send(message.clone()).unwrap(); 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 async_trait::async_trait;
use tracing::Level;
pub struct Svinfo; pub struct Svinfo;
@ -36,12 +37,16 @@ impl Ts6Handler for Svinfo {
assert_eq!(ts_current, TS_CURRENT); assert_eq!(ts_current, TS_CURRENT);
assert_eq!(ts_minimum, TS_MINIMUM); assert_eq!(ts_minimum, TS_MINIMUM);
vec![Ts6Action::SendText(IrcResponse { vec![
sender: None, Ts6Action::SendText(IrcResponse {
command: "SVINFO".to_owned(), sender: None,
receiver: None, command: "SVINFO".to_owned(),
arguments: vec!["6".to_owned(), "6".to_owned(), "0".to_owned()], receiver: None,
message: format!(":{}", current_time), 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, commands::Ts6Command,
structs::{ServerId, UserId}, structs::{ServerId, UserId},
}, },
user::UserUnwrapped,
}; };
#[derive(Clone, Debug, Default)] #[derive(Clone, Debug, Default)]
@ -36,6 +37,33 @@ pub struct Ts6 {
mod commands; mod commands;
pub mod structs; 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 { impl Ts6 {
pub async fn handle_command( pub async fn handle_command(
&mut self, &mut self,
@ -113,33 +141,9 @@ impl Ts6 {
Message::NetJoinMessage(net_join_message) => { Message::NetJoinMessage(net_join_message) => {
let user = net_join_message.user.clone(); let user = net_join_message.user.clone();
// TODO: refactor this entire thing. we need hostmask and ip and such fully working introduce_user(user, my_sid)
IrcResponse { .send(hostname, writer, false)
sender: Some(hostname.to_string()), .await?;
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(),
}
.send(hostname, writer, false)
.await
.unwrap();
} }
Message::PrivMessage(priv_message) => 'priv_message_handler: { Message::PrivMessage(priv_message) => 'priv_message_handler: {