From 8dfb89fe3808bb4b37604001ab3e373d6e142bc0 Mon Sep 17 00:00:00 2001 From: pep Date: Sun, 28 Dec 2025 19:08:19 +0100 Subject: [PATCH] bot: resync on 'rejoin' rather than leave and join The xmpp crate doesn't yet have mechanisms to wait for the next incoming presence and so the `leave_room` method returns after the unavailable presence has been set. Thus the code may still think it's being joined when it pretty soon going not to be. Instead, we chose to send another join presence to signal the MUC we want to get the full state again (occupants, subject), without leaving. Signed-off-by: pep --- Cargo.toml | 2 +- src/bot.rs | 46 ++++++++++++++++++---------------------------- 2 files changed, 19 insertions(+), 29 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e5a0811..474304e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,7 +20,7 @@ pretty_env_logger = "0.5" serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0" toml = "0.9" -xmpp = { git = "https://gitlab.com/xmpp-rs/xmpp-rs", branch = "xmpp-config", default-features = false, features = [ "serde", "starttls", "rustls-native-certs", "aws_lc_rs" ] } +xmpp = { git = "https://gitlab.com/xmpp-rs/xmpp-rs", branch = "xmpp-join-resync", default-features = false, features = [ "serde", "starttls", "rustls-native-certs", "aws_lc_rs" ] } hmac = "0.12" sha2 = "0.10" hex = "0.4" diff --git a/src/bot.rs b/src/bot.rs index 9c2e998..e77477f 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -23,7 +23,7 @@ use xmpp::parsers::message::MessageType; use xmpp::{ Agent, ClientBuilder, ClientFeature, ClientType, Config as AgentConfig, Event, RoomNick, message::send::RawMessageSettings, - muc::room::{JoinRoomSettings, LeaveRoomSettings}, + muc::room::JoinRoomSettings, }; pub struct XmppClient { @@ -69,7 +69,14 @@ impl XmppClient { Event::Online => { self.is_online = true; debug!("XMPP Online"); - self.join_rooms().await + for room in &self.rooms { + self.agent + .join_room(JoinRoomSettings { + nick: Some(RoomNick::from_resource_ref(self.nickname.as_ref())), + ..JoinRoomSettings::new(room.clone()) + }) + .await + } } Event::ChatMessage(_id, bare, message, _timeinfo) => { if !self.admins.contains(&bare) { @@ -80,8 +87,15 @@ impl XmppClient { debug!("Received chat message from {}: {}", bare, message); if message == "rejoin" { - self.leave_rooms().await; - self.join_rooms().await + for room in &self.rooms { + self.agent + .join_room(JoinRoomSettings { + nick: Some(RoomNick::from_resource_ref(self.nickname.as_ref())), + force_resync: true, + ..JoinRoomSettings::new(room.clone()) + }) + .await + } } } Event::Disconnected(e) => { @@ -95,30 +109,6 @@ impl XmppClient { } } - pub async fn join_rooms(&mut self) { - for room in &self.rooms { - self.agent - .join_room(JoinRoomSettings { - room: room.clone(), - nick: Some(RoomNick::from_resource_ref(self.nickname.as_ref())), - password: None, - status: Some(("en", "Hi there!")), - }) - .await - } - } - - pub async fn leave_rooms(&mut self) { - for room in &self.rooms { - self.agent - .leave_room(LeaveRoomSettings { - room: room.clone(), - status: Some(("en", "See you!")), - }) - .await - } - } - pub async fn receive(&mut self, mut rx: mpsc::UnboundedReceiver) { loop { tokio::select! {