Re-assert +r when a registered channel is created
fedserv now handles FJOIN (channel create/burst) and sets +r on any channel that is registered, so a registered channel regains the mode after it empties and is recreated, and after a services relink. Single joins arrive as IJOIN and are ignored.
This commit is contained in:
parent
64500906d8
commit
eb22612da8
3 changed files with 45 additions and 0 deletions
|
|
@ -170,6 +170,16 @@ impl Engine {
|
|||
self.network.user_nick_change(&uid, nick);
|
||||
Vec::new()
|
||||
}
|
||||
// A registered channel just (re)appeared: re-assert +r. Fires on
|
||||
// creation and on the uplink burst, so registered channels regain the
|
||||
// mode after emptying, and after a services relink.
|
||||
NetEvent::ChannelCreate { channel } => {
|
||||
if self.db.channel(&channel).is_some() {
|
||||
vec![NetAction::ChannelMode { channel, modes: "+r".to_string() }]
|
||||
} else {
|
||||
Vec::new()
|
||||
}
|
||||
}
|
||||
NetEvent::Quit { uid } => {
|
||||
self.network.user_quit(&uid);
|
||||
self.sasl_sessions.remove(&uid); // drop any half-finished exchange
|
||||
|
|
@ -938,4 +948,21 @@ mod tests {
|
|||
assert!(notice(&out, "dropped"));
|
||||
assert!(out.iter().any(|a| matches!(a, NetAction::ChannelMode { channel, modes } if channel == "#room" && modes == "-r")), "drop clears +r: {out:?}");
|
||||
}
|
||||
|
||||
// A registered channel (re)appearing re-asserts +r; an unregistered one does not.
|
||||
#[test]
|
||||
fn channel_create_reasserts_registered_mode() {
|
||||
let path = std::env::temp_dir().join("fedserv-chancreate.jsonl");
|
||||
let _ = std::fs::remove_file(&path);
|
||||
let mut db = Db::open(&path, "42S");
|
||||
db.register_channel("#reg", "alice").unwrap();
|
||||
let ns = NickServ { uid: "42SAAAAAA".into(), guest_nick: "Guest".into(), guest_seq: 0 };
|
||||
let mut e = Engine::new(vec![Box::new(ns)], db);
|
||||
|
||||
let out = e.handle(NetEvent::ChannelCreate { channel: "#reg".into() });
|
||||
assert!(out.iter().any(|a| matches!(a, NetAction::ChannelMode { channel, modes } if channel == "#reg" && modes == "+r")), "registered channel regains +r: {out:?}");
|
||||
|
||||
let out = e.handle(NetEvent::ChannelCreate { channel: "#other".into() });
|
||||
assert!(out.is_empty(), "unregistered channel is left alone: {out:?}");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,6 +90,11 @@ impl Protocol for InspIrcd {
|
|||
}
|
||||
_ => vec![],
|
||||
},
|
||||
// FJOIN <chan> <ts> <modes> [params] :<members> — channel create/burst.
|
||||
"FJOIN" => match tokens.next() {
|
||||
Some(chan) if !chan.is_empty() => vec![NetEvent::ChannelCreate { channel: chan.to_string() }],
|
||||
_ => vec![],
|
||||
},
|
||||
"QUIT" => vec![NetEvent::Quit { uid: source.unwrap_or_default() }],
|
||||
// account-registration relay from an ircd:
|
||||
// ACCTREGISTER <reqid> <origin> <kind> <account> <p2> :<p3>
|
||||
|
|
@ -232,4 +237,14 @@ mod tests {
|
|||
"{ev:?}"
|
||||
);
|
||||
}
|
||||
|
||||
// FJOIN (channel create/burst) surfaces as ChannelCreate for the channel.
|
||||
#[test]
|
||||
fn parses_fjoin_as_channel_create() {
|
||||
let ev = proto().parse(":0IR FJOIN #chan 1783845132 +tn :o,0IRAAAAAB:0");
|
||||
assert!(
|
||||
matches!(ev.as_slice(), [NetEvent::ChannelCreate { channel }] if channel == "#chan"),
|
||||
"{ev:?}"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -12,6 +12,9 @@ pub enum NetEvent {
|
|||
Privmsg { from: String, to: String, text: String },
|
||||
UserConnect { uid: String, nick: String },
|
||||
NickChange { uid: String, nick: String },
|
||||
// A channel was created or bursted (InspIRCd FJOIN). Subsequent single joins
|
||||
// arrive as IJOIN and are not surfaced.
|
||||
ChannelCreate { channel: String },
|
||||
Quit { uid: String },
|
||||
// An ircd relaying an IRCv3 account-registration request to us as the authority.
|
||||
AccountRequest { reqid: String, origin: String, kind: String, account: String, p2: String, p3: String },
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue