add SIGNORE: personal mutual server-side ignore across channels and PMs
This commit is contained in:
parent
2c9ce18cd7
commit
6c5f330746
5 changed files with 107 additions and 1 deletions
|
|
@ -599,7 +599,8 @@ pub(crate) fn deliver(s: &mut Server, uid: Uid, params: &[String], notice: bool)
|
|||
}
|
||||
// SILENCE: if the recipient silenced the sender, drop it silently — the
|
||||
// sender is never told (that's the point), but still gets their own echo.
|
||||
let silenced = s.is_silenced(tuid, &prefix);
|
||||
// SIGNORE is mutual: drop if either party server-ignores the other.
|
||||
let silenced = s.is_silenced(tuid, &prefix) || s.signore_blocks(uid, tuid);
|
||||
let pm = format!(":{prefix} {cmd} {target} :{text}");
|
||||
let ctags = s.line_ctags.clone();
|
||||
let msgid = s.next_msgid();
|
||||
|
|
|
|||
|
|
@ -14,6 +14,7 @@ pub fn commands() -> Vec<Box<dyn Command>> {
|
|||
Box::new(Watch),
|
||||
Box::new(Monitor),
|
||||
Box::new(Silence),
|
||||
Box::new(Signore),
|
||||
Box::new(Accept),
|
||||
]
|
||||
}
|
||||
|
|
@ -298,6 +299,77 @@ impl Command for Silence {
|
|||
}
|
||||
}
|
||||
|
||||
// --- SIGNORE (personal mutual server-side ignore) ---------------------------
|
||||
|
||||
fn signore_list(s: &Server, uid: Uid) {
|
||||
let (nick, list) = s
|
||||
.users
|
||||
.get(&uid)
|
||||
.map(|u| (u.nick.clone(), u.signore.clone()))
|
||||
.unwrap_or_default();
|
||||
let sn = &s.name;
|
||||
if list.is_empty() {
|
||||
s.send(uid, format!(":{sn} NOTICE {nick} :Your SIGNORE list is empty."));
|
||||
} else {
|
||||
for m in &list {
|
||||
s.send(uid, format!(":{sn} NOTICE {nick} :SIGNORE {m}"));
|
||||
}
|
||||
}
|
||||
s.send(uid, format!(":{sn} NOTICE {nick} :End of SIGNORE list."));
|
||||
}
|
||||
|
||||
/// SIGNORE — a personal, mutual server-side ignore. `SIGNORE <mask>` (or `+mask`)
|
||||
/// blocks a user both ways: neither of you sees the other's channel or private
|
||||
/// messages. `SIGNORE -<mask>` lifts it; a bare `SIGNORE` lists your masks. A bare
|
||||
/// nick becomes `nick!*@*`.
|
||||
struct Signore;
|
||||
impl Command for Signore {
|
||||
fn name(&self) -> &'static str {
|
||||
"SIGNORE"
|
||||
}
|
||||
fn handle(&self, s: &mut Server, uid: Uid, params: &[String]) -> CmdResult {
|
||||
let Some(arg) = params.first() else {
|
||||
signore_list(s, uid);
|
||||
return CmdResult::Ok;
|
||||
};
|
||||
let nick = s.users.get(&uid).map(|u| u.nick.clone()).unwrap_or_default();
|
||||
let sn = s.name.clone();
|
||||
let (add, raw) = match arg.strip_prefix('-') {
|
||||
Some(m) => (false, m),
|
||||
None => (true, arg.strip_prefix('+').unwrap_or(arg)),
|
||||
};
|
||||
if raw.is_empty() {
|
||||
signore_list(s, uid);
|
||||
return CmdResult::Ok;
|
||||
}
|
||||
let mask = normalize_mask(raw);
|
||||
if add {
|
||||
let max = s.conf_num("maxsignore", 64usize);
|
||||
let full = s
|
||||
.users
|
||||
.get(&uid)
|
||||
.map(|u| u.signore.len() >= max && !u.signore.contains(&mask))
|
||||
.unwrap_or(true);
|
||||
if full {
|
||||
s.send(uid, format!(":{sn} NOTICE {nick} :Your SIGNORE list is full ({max} max)."));
|
||||
return CmdResult::Fail;
|
||||
}
|
||||
if let Some(u) = s.users.get_mut(&uid) {
|
||||
if !u.signore.contains(&mask) {
|
||||
u.signore.push(mask.clone());
|
||||
}
|
||||
}
|
||||
s.send(uid, format!(":{sn} NOTICE {nick} :SIGNORE \x02{mask}\x02 added — you and they can no longer see each other's messages."));
|
||||
} else {
|
||||
if let Some(u) = s.users.get_mut(&uid) {
|
||||
u.signore.retain(|x| x != &mask);
|
||||
}
|
||||
s.send(uid, format!(":{sn} NOTICE {nick} :SIGNORE \x02{mask}\x02 removed."));
|
||||
}
|
||||
CmdResult::Ok
|
||||
}
|
||||
}
|
||||
|
||||
// --- ACCEPT (callerid +g allow-list) ----------------------------------------
|
||||
|
||||
fn accept_list(s: &Server, uid: Uid) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue