helpmode: oper-settable user mode +h (helpop) shown in whois
This commit is contained in:
parent
512185d6df
commit
71d6e7441b
4 changed files with 34 additions and 2 deletions
|
|
@ -120,6 +120,8 @@ amu_target = both
|
||||||
# --- chanlog (m_chanlog): mirror the oper server-notice stream into a channel so
|
# --- chanlog (m_chanlog): mirror the oper server-notice stream into a channel so
|
||||||
# staff can watch it in a normal window. Set the channel (create/keep it opped):
|
# staff can watch it in a normal window. Set the channel (create/keep it opped):
|
||||||
# chanlog = #snotices
|
# chanlog = #snotices
|
||||||
|
# --- helpmode (m_helpmode): no config — adds oper-settable user mode +h (helpop),
|
||||||
|
# which shows "is available for help" in the user's WHOIS.
|
||||||
# --- globops (m_globops): no config — adds the oper command /GLOBOPS <message>,
|
# --- globops (m_globops): no config — adds the oper command /GLOBOPS <message>,
|
||||||
# broadcasting to all opers (like the server-notice stream).
|
# broadcasting to all opers (like the server-notice stream).
|
||||||
# --- autodrop (m_autodrop): silently drop a not-yet-registered client that sends
|
# --- autodrop (m_autodrop): silently drop a not-yet-registered client that sends
|
||||||
|
|
|
||||||
|
|
@ -253,6 +253,10 @@ impl Command for Whois {
|
||||||
if let Some(line) = crate::modules::profilelink::line(s, &account) {
|
if let Some(line) = crate::modules::profilelink::line(s, &account) {
|
||||||
s.numeric(uid, RPL_WHOISSPECIAL, &format!(":{line}"));
|
s.numeric(uid, RPL_WHOISSPECIAL, &format!(":{line}"));
|
||||||
}
|
}
|
||||||
|
// helpmode: +h marks a user available for help (visible to everyone)
|
||||||
|
if s.users.get(&tuid).map(|u| u.flags.helpop).unwrap_or(false) {
|
||||||
|
s.numeric(uid, RPL_WHOISSPECIAL, ":is available for help.");
|
||||||
|
}
|
||||||
// customtitle: a claimed vanity title
|
// customtitle: a claimed vanity title
|
||||||
if let Some(line) = crate::modules::customtitle::line(s, tuid) {
|
if let Some(line) = crate::modules::customtitle::line(s, tuid) {
|
||||||
s.numeric(uid, RPL_WHOISSPECIAL, &format!(":{line}"));
|
s.numeric(uid, RPL_WHOISSPECIAL, &format!(":{line}"));
|
||||||
|
|
|
||||||
24
src/mode.rs
24
src/mode.rs
|
|
@ -1064,6 +1064,7 @@ pub fn user_mode(c: char) -> Option<&'static (dyn UserMode + Sync)> {
|
||||||
static USER_MODES: &[&(dyn UserMode + Sync)] = &[
|
static USER_MODES: &[&(dyn UserMode + Sync)] = &[
|
||||||
&INVISIBLE,
|
&INVISIBLE,
|
||||||
&WALLOPS,
|
&WALLOPS,
|
||||||
|
&HELPOP,
|
||||||
&OPER,
|
&OPER,
|
||||||
&CLOAK,
|
&CLOAK,
|
||||||
&BOT,
|
&BOT,
|
||||||
|
|
@ -1196,6 +1197,27 @@ impl UserMode for OperMode {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// `+h` — helpop: marks a user as available for help (shown in WHOIS). Only opers
|
||||||
|
/// may set it on themselves; anyone may clear it.
|
||||||
|
struct HelpMode;
|
||||||
|
static HELPOP: HelpMode = HelpMode;
|
||||||
|
impl UserMode for HelpMode {
|
||||||
|
fn letter(&self) -> char {
|
||||||
|
'h'
|
||||||
|
}
|
||||||
|
fn apply(&self, s: &mut Server, uid: Uid, adding: bool) -> bool {
|
||||||
|
if adding && !s.is_oper(uid) {
|
||||||
|
return false; // only opers may declare themselves a helpop
|
||||||
|
}
|
||||||
|
if let Some(u) = s.users.get_mut(&uid) {
|
||||||
|
u.flags.helpop = adding;
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// `+x` — host cloaking. The cloak string is computed once at connect by
|
/// `+x` — host cloaking. The cloak string is computed once at connect by
|
||||||
/// [`crate::modules::cloak`]; this handler only toggles whether it's shown.
|
/// [`crate::modules::cloak`]; this handler only toggles whether it's shown.
|
||||||
/// `-x` (revealing the real host) is oper-only, so +x can't be flipped to dodge
|
/// `-x` (revealing the real host) is oper-only, so +x can't be flipped to dodge
|
||||||
|
|
@ -1301,7 +1323,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn registry_covers_all_user_modes() {
|
fn registry_covers_all_user_modes() {
|
||||||
for c in "iwoxBDIHrRzsgWc".chars() {
|
for c in "iwoxBDIHrRzsgWhc".chars() {
|
||||||
assert!(user_mode(c).is_some(), "missing umode +{c}");
|
assert!(user_mode(c).is_some(), "missing umode +{c}");
|
||||||
}
|
}
|
||||||
assert!(user_mode('Q').is_none());
|
assert!(user_mode('Q').is_none());
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,7 @@ pub struct UserFlags {
|
||||||
pub snomask: bool, // +s (oper: receive server notices)
|
pub snomask: bool, // +s (oper: receive server notices)
|
||||||
pub callerid: bool, // +g (only accept PMs from users on the ACCEPT list)
|
pub callerid: bool, // +g (only accept PMs from users on the ACCEPT list)
|
||||||
pub showwhois: bool, // +W (get a notice when someone WHOISes you)
|
pub showwhois: bool, // +W (get a notice when someone WHOISes you)
|
||||||
|
pub helpop: bool, // +h (helpop: available for help; shown in WHOIS)
|
||||||
pub deny_uncommon: bool, // +c (only users sharing a channel may PM you)
|
pub deny_uncommon: bool, // +c (only users sharing a channel may PM you)
|
||||||
pub nick_locked: bool, // NICKLOCK: services/oper holds this nick (no self-change)
|
pub nick_locked: bool, // NICKLOCK: services/oper holds this nick (no self-change)
|
||||||
pub via_webirc: bool, // connected through a WEBIRC gateway (securitygroups)
|
pub via_webirc: bool, // connected through a WEBIRC gateway (securitygroups)
|
||||||
|
|
@ -82,6 +83,9 @@ impl UserFlags {
|
||||||
if self.showwhois {
|
if self.showwhois {
|
||||||
s.push('W');
|
s.push('W');
|
||||||
}
|
}
|
||||||
|
if self.helpop {
|
||||||
|
s.push('h');
|
||||||
|
}
|
||||||
if self.deny_uncommon {
|
if self.deny_uncommon {
|
||||||
s.push('c');
|
s.push('c');
|
||||||
}
|
}
|
||||||
|
|
@ -465,7 +469,7 @@ impl Server {
|
||||||
uid,
|
uid,
|
||||||
RPL_MYINFO,
|
RPL_MYINFO,
|
||||||
&format!(
|
&format!(
|
||||||
"{} echoircd-{VERSION} iowxsgBDIHrRzWc qaohvbeIklimnpstzCTcSNORMfjFLgGuBQAPJUdKXwD",
|
"{} echoircd-{VERSION} iowxsgBDIHrRzWhc qaohvbeIklimnpstzCTcSNORMfjFLgGuBQAPJUdKXwD",
|
||||||
self.name
|
self.name
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue