From c1b7ed6dda01c7be9884772e3d8aadcd6df33c67 Mon Sep 17 00:00:00 2001 From: reverse Date: Mon, 17 Aug 2026 14:52:38 +0000 Subject: [PATCH] channel: count remote members for +l, and propagate TBAN expiry (-b) over S2S --- src/channels.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/channels.rs b/src/channels.rs index a63045d..5f781d2 100644 --- a/src/channels.rs +++ b/src/channels.rs @@ -601,6 +601,10 @@ impl Server { ch.bans.retain(|b| b.mask != mask); } self.to_channel(&key, &format!(":{} MODE {name} -b {mask}", self.name), None); + // Propagate the removal to linked servers, else they keep the ban + // forever (they stored the original +b without its expiry). + let sid = self.sid.clone(); + self.propagate_chan_mode(&sid, &name, "-b", &[mask]); } } @@ -808,9 +812,14 @@ impl Server { } } } - // +l full — with +L redirect, bounce the user to the target instead (opers override) + // +l full — with +L redirect, bounce the user to the target instead (opers override). + // Count every member, local AND remote (services/other-server users), so the + // limit reflects the channel's real network-wide size like InspIRCd. if let Some(ch) = self.channels.get(&key) { - let full = ch.modes.limit.is_some_and(|l| ch.members.len() as u32 >= l); + let full = ch + .modes + .limit + .is_some_and(|l| (ch.members.len() + ch.rmembers.len()) as u32 >= l); let redirect = ch.modes.redirect.clone(); if full && is_oper { overrode = true;