chanserv: SET SIGNKICK and PRIVATE (typed channel settings)
Introduce a typed ChanSettings struct + ChanSetting enum for ChanServ's on/off options instead of a bag of string flags, so a new option is one field and the compiler proves every site handles it. First two, both functional: SIGNKICK attributes ChanServ kicks with who requested them; PRIVATE hides the channel from LIST. Folded through the event log like the other channel state (node-local, no gossip), shown in INFO. One ChannelSettingsSet event, one Store method.
This commit is contained in:
parent
f388e3d650
commit
75019c867a
7 changed files with 114 additions and 10 deletions
|
|
@ -15,6 +15,10 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, net:
|
|||
ctx.notice(me, from.uid, format!("\x02{nick}\x02 isn't here."));
|
||||
return;
|
||||
};
|
||||
let reason = if args.len() > 3 { args[3..].join(" ") } else { "Kicked".to_string() };
|
||||
let mut reason = if args.len() > 3 { args[3..].join(" ") } else { "Kicked".to_string() };
|
||||
// SIGNKICK: attribute the kick to whoever asked for it.
|
||||
if db.channel(chan).is_some_and(|c| c.signkick) {
|
||||
reason = format!("{reason} (requested by {})", from.nick);
|
||||
}
|
||||
ctx.kick(me, chan, target, &reason);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -101,6 +101,12 @@ impl Service for ChanServ {
|
|||
ctx.notice(me, from.uid, format!(" Description: {}", info.desc));
|
||||
}
|
||||
ctx.notice(me, from.uid, format!(" Registered : {}", fedserv_api::human_time(info.ts)));
|
||||
let mut opts = Vec::new();
|
||||
if info.signkick { opts.push("SIGNKICK"); }
|
||||
if info.private { opts.push("PRIVATE"); }
|
||||
if !opts.is_empty() {
|
||||
ctx.notice(me, from.uid, format!(" Options : {}", opts.join(", ")));
|
||||
}
|
||||
}
|
||||
None => ctx.notice(me, from.uid, format!("\x02{chan}\x02 isn't registered.")),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,7 +3,8 @@ use fedserv_api::{Sender, ServiceCtx};
|
|||
|
||||
// LIST: show all registered channels.
|
||||
pub fn handle(me: &str, from: &Sender, _args: &[&str], ctx: &mut ServiceCtx, db: &dyn Store) {
|
||||
let mut names: Vec<String> = db.channels().into_iter().map(|c| c.name).collect();
|
||||
// PRIVATE channels are hidden from LIST.
|
||||
let mut names: Vec<String> = db.channels().into_iter().filter(|c| !c.private).map(|c| c.name).collect();
|
||||
if names.is_empty() {
|
||||
ctx.notice(me, from.uid, "No channels are registered.");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,4 @@
|
|||
use fedserv_api::Store;
|
||||
use fedserv_api::{Sender, ServiceCtx};
|
||||
use fedserv_api::{ChanSetting, Sender, ServiceCtx, Store};
|
||||
|
||||
// SET <#channel> FOUNDER <account> | DESC <text>: founder-only channel settings.
|
||||
pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store) {
|
||||
|
|
@ -40,6 +39,24 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, db:
|
|||
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||
}
|
||||
}
|
||||
_ => ctx.notice(me, from.uid, "Syntax: SET <#channel> FOUNDER <account> | DESC <text>"),
|
||||
Some("SIGNKICK") => toggle(me, from, ctx, db, chan, ChanSetting::SignKick, args.get(3).copied(), "SIGNKICK"),
|
||||
Some("PRIVATE") => toggle(me, from, ctx, db, chan, ChanSetting::Private, args.get(3).copied(), "PRIVATE"),
|
||||
_ => ctx.notice(me, from.uid, "Syntax: SET <#channel> FOUNDER <account> | DESC <text> | SIGNKICK {ON|OFF} | PRIVATE {ON|OFF}"),
|
||||
}
|
||||
}
|
||||
|
||||
// Flip one on/off channel option, reporting the new state.
|
||||
fn toggle(me: &str, from: &Sender, ctx: &mut ServiceCtx, db: &mut dyn Store, chan: &str, setting: ChanSetting, arg: Option<&str>, name: &str) {
|
||||
let on = match arg.map(|s| s.to_ascii_uppercase()).as_deref() {
|
||||
Some("ON") => true,
|
||||
Some("OFF") => false,
|
||||
_ => {
|
||||
ctx.notice(me, from.uid, format!("Syntax: SET <#channel> {name} {{ON|OFF}}"));
|
||||
return;
|
||||
}
|
||||
};
|
||||
match db.set_channel_setting(chan, setting, on) {
|
||||
Ok(()) => ctx.notice(me, from.uid, format!("\x02{name}\x02 for \x02{chan}\x02 is now \x02{}\x02.", if on { "on" } else { "off" })),
|
||||
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue