ChanServ: add SET SUCCESSOR with founder inheritance
All checks were successful
CI / check (push) Successful in 3m59s
All checks were successful
CI / check (push) Successful in 3m59s
SET <#channel> SUCCESSOR <account>|OFF names an account that inherits the channel if the founder's account is dropped or expires, instead of the channel being released. Adds a ChannelInfo.successor field + event, and centralises the founder-gone channel release into a single release_founded_channels store method used by DROP, expiry, and the gossip account-gone path so all three transfer consistently.
This commit is contained in:
parent
6e3a758cc1
commit
ac50af92fc
11 changed files with 141 additions and 14 deletions
|
|
@ -51,7 +51,7 @@ const TOPICS: &[HelpEntry] = &[
|
|||
HelpEntry { cmd: "REGISTER", summary: "register a channel", detail: "Syntax: \x02REGISTER <#channel>\x02\nRegisters a channel to you. You must currently hold ops in it." },
|
||||
HelpEntry { cmd: "INFO", summary: "show channel information", detail: "Syntax: \x02INFO <#channel>\x02\nShows a channel's registration and settings." },
|
||||
HelpEntry { cmd: "LIST", summary: "list registered channels", detail: "Syntax: \x02LIST\x02\nLists registered channels." },
|
||||
HelpEntry { cmd: "SET", summary: "change founder or settings", detail: "Syntax: \x02SET <#channel> FOUNDER <account> | DESC <text> | SIGNKICK|PRIVATE|PEACE|SECUREOPS|KEEPTOPIC|TOPICLOCK {ON|OFF}\x02\nTransfers the founder or changes a channel setting." },
|
||||
HelpEntry { cmd: "SET", summary: "change founder or settings", detail: "Syntax: \x02SET <#channel> FOUNDER <account> | DESC <text> | SUCCESSOR <account>|OFF | SIGNKICK|PRIVATE|PEACE|SECUREOPS|KEEPTOPIC|TOPICLOCK {ON|OFF}\x02\nTransfers the founder or changes a channel setting." },
|
||||
HelpEntry { cmd: "ACCESS", summary: "manage the access list", detail: "Syntax: \x02ACCESS <#channel> LIST | ADD <account> <op|voice> | DEL <account>\x02\nManages the channel access list." },
|
||||
HelpEntry { cmd: "FLAGS", summary: "granular per-account flags", detail: "Syntax: \x02FLAGS <#channel> [account [+/-flags]]\x02\nViews or changes granular per-account channel flags." },
|
||||
HelpEntry { cmd: "AOP/SOP/VOP", summary: "tiered access shortcuts", detail: "Syntax: \x02AOP|SOP|VOP <#channel> ADD <account> | DEL <account> | LIST\x02\nTiered shortcuts over ACCESS: AOP and SOP grant op, VOP grants voice." },
|
||||
|
|
|
|||
|
|
@ -35,6 +35,28 @@ 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."),
|
||||
}
|
||||
}
|
||||
Some("SUCCESSOR") => {
|
||||
match args.get(3) {
|
||||
Some(&acct) if !acct.eq_ignore_ascii_case("OFF") => {
|
||||
if !db.exists(acct) {
|
||||
ctx.notice(me, from.uid, format!("\x02{acct}\x02 isn't a registered account."));
|
||||
return;
|
||||
}
|
||||
if acct.eq_ignore_ascii_case(&founder) {
|
||||
ctx.notice(me, from.uid, "The successor must be someone other than the founder.");
|
||||
return;
|
||||
}
|
||||
match db.set_successor(chan, Some(acct)) {
|
||||
Ok(()) => ctx.notice(me, from.uid, format!("Successor of \x02{chan}\x02 set to \x02{acct}\x02. They inherit it if your account is dropped or expires.")),
|
||||
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||
}
|
||||
}
|
||||
_ => match db.set_successor(chan, None) {
|
||||
Ok(()) => ctx.notice(me, from.uid, format!("Successor of \x02{chan}\x02 cleared.")),
|
||||
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||
},
|
||||
}
|
||||
}
|
||||
Some("DESC") => {
|
||||
let desc = if args.len() > 3 { args[3..].join(" ") } else { String::new() };
|
||||
match db.set_desc(chan, &desc) {
|
||||
|
|
@ -48,7 +70,7 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, db:
|
|||
Some("SECUREOPS") => toggle(me, from, ctx, db, chan, ChanSetting::SecureOps, args.get(3).copied()),
|
||||
Some("KEEPTOPIC") => toggle(me, from, ctx, db, chan, ChanSetting::KeepTopic, args.get(3).copied()),
|
||||
Some("TOPICLOCK") => toggle(me, from, ctx, db, chan, ChanSetting::TopicLock, args.get(3).copied()),
|
||||
_ => ctx.notice(me, from.uid, "Syntax: SET <#channel> FOUNDER <account> | DESC <text> | SIGNKICK {ON|OFF} | PRIVATE {ON|OFF} | PEACE {ON|OFF} | SECUREOPS {ON|OFF} | KEEPTOPIC {ON|OFF} | TOPICLOCK {ON|OFF}"),
|
||||
_ => ctx.notice(me, from.uid, "Syntax: SET <#channel> FOUNDER <account> | SUCCESSOR <account>|OFF | DESC <text> | SIGNKICK {ON|OFF} | PRIVATE {ON|OFF} | PEACE {ON|OFF} | SECUREOPS {ON|OFF} | KEEPTOPIC {ON|OFF} | TOPICLOCK {ON|OFF}"),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -17,9 +17,9 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, net:
|
|||
ctx.notice(me, from.uid, "Invalid password.");
|
||||
return;
|
||||
}
|
||||
let channels = db.channels_owned_by(account);
|
||||
for chan in &channels {
|
||||
let _ = db.drop_channel(chan);
|
||||
// A channel with a successor is inherited; the rest are dropped and released.
|
||||
let (inherited, dropped) = db.release_founded_channels(account);
|
||||
for chan in &dropped {
|
||||
ctx.channel_mode("", chan, "-r"); // server-sourced: release the registered mode
|
||||
}
|
||||
let _ = db.drop_account(account);
|
||||
|
|
@ -27,7 +27,11 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, net:
|
|||
ctx.logout(&uid);
|
||||
}
|
||||
ctx.notice(me, from.uid, format!("Your account \x02{account}\x02 has been dropped."));
|
||||
if !channels.is_empty() {
|
||||
ctx.notice(me, from.uid, format!("Channels released: {}.", channels.join(", ")));
|
||||
if !dropped.is_empty() {
|
||||
ctx.notice(me, from.uid, format!("Channels released: {}.", dropped.join(", ")));
|
||||
}
|
||||
if !inherited.is_empty() {
|
||||
let list: Vec<String> = inherited.iter().map(|(c, s)| format!("{c} -> {s}")).collect();
|
||||
ctx.notice(me, from.uid, format!("Channels passed to their successor: {}.", list.join(", ")));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue