BotServ: add BOTLIST and AUTOASSIGN default bot
All checks were successful
CI / check (push) Successful in 3m33s
All checks were successful
CI / check (push) Successful in 3m33s
This commit is contained in:
parent
cd6d8b1b93
commit
dd43b9a331
12 changed files with 162 additions and 0 deletions
34
modules/botserv/src/autoassign.rs
Normal file
34
modules/botserv/src/autoassign.rs
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
use echo_api::{Priv, Sender, ServiceCtx, Store};
|
||||
|
||||
// AUTOASSIGN <bot> | OFF: set the bot automatically assigned to every newly
|
||||
// registered channel, or turn auto-assignment off. Oper-only (Priv::Admin) —
|
||||
// it's a network-wide default. No argument reports the current setting.
|
||||
pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, db: &mut dyn Store) {
|
||||
if !from.privs.has(Priv::Admin) {
|
||||
ctx.notice(me, from.uid, "Access denied — AUTOASSIGN is for services operators.");
|
||||
return;
|
||||
}
|
||||
let Some(&arg) = args.get(1) else {
|
||||
match db.default_bot() {
|
||||
Some(bot) => ctx.notice(me, from.uid, format!("New channels are auto-assigned \x02{bot}\x02. Use \x02AUTOASSIGN OFF\x02 to stop.")),
|
||||
None => ctx.notice(me, from.uid, "No bot is auto-assigned to new channels. Set one with \x02AUTOASSIGN <bot>\x02."),
|
||||
}
|
||||
return;
|
||||
};
|
||||
if arg.eq_ignore_ascii_case("OFF") || arg.eq_ignore_ascii_case("NONE") {
|
||||
match db.set_default_bot(None) {
|
||||
Ok(()) => ctx.notice(me, from.uid, "New channels will no longer be auto-assigned a bot."),
|
||||
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||
}
|
||||
return;
|
||||
}
|
||||
// Store the bot's canonical nick, so the setting survives a re-cased lookup.
|
||||
let Some(bot) = db.bots().into_iter().find(|b| b.nick.eq_ignore_ascii_case(arg)) else {
|
||||
ctx.notice(me, from.uid, format!("There's no bot named \x02{arg}\x02. See \x02BOTLIST\x02."));
|
||||
return;
|
||||
};
|
||||
match db.set_default_bot(Some(&bot.nick)) {
|
||||
Ok(()) => ctx.notice(me, from.uid, format!("New channels will be auto-assigned \x02{}\x02.", bot.nick)),
|
||||
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||
}
|
||||
}
|
||||
19
modules/botserv/src/botlist.rs
Normal file
19
modules/botserv/src/botlist.rs
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
use echo_api::{Priv, Sender, ServiceCtx, Store};
|
||||
|
||||
// BOTLIST: show the bots a channel founder can assign. Available to everyone,
|
||||
// unlike \x02BOT LIST\x02 (operator bot administration). Private bots are hidden
|
||||
// from ordinary users but shown, flagged, to operators.
|
||||
pub fn handle(me: &str, from: &Sender, ctx: &mut ServiceCtx, db: &dyn Store) {
|
||||
let is_oper = from.privs.has(Priv::Admin);
|
||||
let bots: Vec<_> = db.bots().into_iter().filter(|b| is_oper || !b.private).collect();
|
||||
if bots.is_empty() {
|
||||
ctx.notice(me, from.uid, "No bots are available.");
|
||||
return;
|
||||
}
|
||||
ctx.notice(me, from.uid, format!("Available bots ({}):", bots.len()));
|
||||
for b in &bots {
|
||||
let flag = if b.private { " \x02[private]\x02" } else { "" };
|
||||
ctx.notice(me, from.uid, format!(" \x02{}\x02 ({}@{}){flag}", b.nick, b.user, b.host));
|
||||
}
|
||||
ctx.notice(me, from.uid, "Assign one with \x02ASSIGN <#channel> <bot>\x02.");
|
||||
}
|
||||
|
|
@ -6,6 +6,10 @@ use echo_api::{HelpEntry, NetView, Priv, Sender, Service, ServiceCtx, Store};
|
|||
|
||||
#[path = "bot.rs"]
|
||||
mod bot;
|
||||
#[path = "botlist.rs"]
|
||||
mod botlist;
|
||||
#[path = "autoassign.rs"]
|
||||
mod autoassign;
|
||||
#[path = "assign.rs"]
|
||||
mod assign;
|
||||
#[path = "info.rs"]
|
||||
|
|
@ -50,6 +54,8 @@ const TOPICS: &[HelpEntry] = &[
|
|||
HelpEntry { cmd: "BADWORDS", summary: "manage badword patterns", detail: "Syntax: \x02BADWORDS <#channel> ADD|DEL|LIST|CLEAR [pattern]\x02\nManages the channel's badword patterns." },
|
||||
HelpEntry { cmd: "TRIGGER", summary: "manage auto-responses", detail: "Syntax: \x02TRIGGER <#channel> ADD <regex>|<response>[|<cooldown>] | DEL <num> | LIST | CLEAR\x02\nManages the channel's auto-response triggers." },
|
||||
HelpEntry { cmd: "COPY", summary: "clone bot settings", detail: "Syntax: \x02COPY <#source> <#dest>\x02\nClones a channel's bot settings to another channel." },
|
||||
HelpEntry { cmd: "BOTLIST", summary: "list assignable bots", detail: "Syntax: \x02BOTLIST\x02\nLists the service bots you can assign to a channel." },
|
||||
HelpEntry { cmd: "AUTOASSIGN", summary: "default bot for new channels (operator)", detail: "Syntax: \x02AUTOASSIGN <bot> | OFF\x02\nSets the bot auto-assigned to every newly registered channel. Operators only." },
|
||||
HelpEntry { cmd: "BOT", summary: "manage the bots (operator)", detail: "Syntax: \x02BOT ADD|CHANGE|DEL|LIST\x02\nCreates and manages the service bots themselves. Operators only." },
|
||||
];
|
||||
|
||||
|
|
@ -76,6 +82,8 @@ impl Service for BotServ {
|
|||
let me = self.uid.as_str();
|
||||
match args.first().map(|s| s.to_ascii_uppercase()).as_deref() {
|
||||
Some("BOT") => bot::handle(me, from, args, ctx, db),
|
||||
Some("BOTLIST") => botlist::handle(me, from, ctx, db),
|
||||
Some("AUTOASSIGN") => autoassign::handle(me, from, args, ctx, db),
|
||||
Some("ASSIGN") => assign::handle(me, from, args, ctx, db, true),
|
||||
Some("UNASSIGN") => assign::handle(me, from, args, ctx, db, false),
|
||||
Some("INFO") => info::handle(me, from, args, ctx, db),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue