ChanServ: add SET EMAIL channel contact address
Founders can attach a contact email to a channel, shown in INFO and cleared when set empty. Mirrors SET URL exactly; Local-scope channel metadata. Completes the channel DESC/URL/EMAIL trio.
This commit is contained in:
parent
7eb1adce5e
commit
01ea0fa95e
10 changed files with 52 additions and 5 deletions
|
|
@ -744,6 +744,8 @@ pub struct ChannelView {
|
||||||
pub entrymsg: String,
|
pub entrymsg: String,
|
||||||
// Channel homepage URL, shown in INFO (empty = none).
|
// Channel homepage URL, shown in INFO (empty = none).
|
||||||
pub url: String,
|
pub url: String,
|
||||||
|
// Channel contact email, shown in INFO (empty = none).
|
||||||
|
pub email: String,
|
||||||
// ChanServ SET options.
|
// ChanServ SET options.
|
||||||
pub signkick: bool,
|
pub signkick: bool,
|
||||||
pub private: bool,
|
pub private: bool,
|
||||||
|
|
@ -1044,6 +1046,7 @@ pub trait Store {
|
||||||
fn set_mlock(&mut self, name: &str, on: &str, off: &str) -> Result<(), ChanError>;
|
fn set_mlock(&mut self, name: &str, on: &str, off: &str) -> Result<(), ChanError>;
|
||||||
fn set_desc(&mut self, channel: &str, desc: &str) -> Result<(), ChanError>;
|
fn set_desc(&mut self, channel: &str, desc: &str) -> Result<(), ChanError>;
|
||||||
fn set_url(&mut self, channel: &str, url: &str) -> Result<(), ChanError>;
|
fn set_url(&mut self, channel: &str, url: &str) -> Result<(), ChanError>;
|
||||||
|
fn set_channel_email(&mut self, channel: &str, email: &str) -> Result<(), ChanError>;
|
||||||
fn set_channel_setting(&mut self, channel: &str, setting: ChanSetting, on: bool) -> Result<(), ChanError>;
|
fn set_channel_setting(&mut self, channel: &str, setting: ChanSetting, on: bool) -> Result<(), ChanError>;
|
||||||
fn set_kicker(&mut self, channel: &str, kicker: Kicker, on: bool) -> Result<(), ChanError>;
|
fn set_kicker(&mut self, channel: &str, kicker: Kicker, on: bool) -> Result<(), ChanError>;
|
||||||
fn set_caps_kicker(&mut self, channel: &str, caps_min: u16, caps_percent: u16) -> Result<(), ChanError>;
|
fn set_caps_kicker(&mut self, channel: &str, caps_min: u16, caps_percent: u16) -> Result<(), ChanError>;
|
||||||
|
|
|
||||||
|
|
@ -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: "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: "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: "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> | URL [address] | SUCCESSOR <account>|OFF | SIGNKICK|PRIVATE|PEACE|SECUREOPS|RESTRICTED|AUTOOP|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> | URL [address] | EMAIL [address] | SUCCESSOR <account>|OFF | SIGNKICK|PRIVATE|PEACE|SECUREOPS|RESTRICTED|AUTOOP|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: "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: "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." },
|
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." },
|
||||||
|
|
@ -160,6 +160,9 @@ impl Service for ChanServ {
|
||||||
if !info.url.is_empty() {
|
if !info.url.is_empty() {
|
||||||
ctx.notice(me, from.uid, format!(" URL : {}", info.url));
|
ctx.notice(me, from.uid, format!(" URL : {}", info.url));
|
||||||
}
|
}
|
||||||
|
if !info.email.is_empty() {
|
||||||
|
ctx.notice(me, from.uid, format!(" Email : {}", info.email));
|
||||||
|
}
|
||||||
ctx.notice(me, from.uid, format!(" Registered : {}", echo_api::human_time(info.ts)));
|
ctx.notice(me, from.uid, format!(" Registered : {}", echo_api::human_time(info.ts)));
|
||||||
if let Some(s) = db.channel_suspension(chan) {
|
if let Some(s) = db.channel_suspension(chan) {
|
||||||
ctx.notice(me, from.uid, format!(" Suspended : by \x02{}\x02 — {}", s.by, s.reason));
|
ctx.notice(me, from.uid, format!(" Suspended : by \x02{}\x02 — {}", s.by, s.reason));
|
||||||
|
|
|
||||||
|
|
@ -72,6 +72,14 @@ 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."),
|
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some("EMAIL") => {
|
||||||
|
let email = args.get(3).copied().unwrap_or("");
|
||||||
|
match db.set_channel_email(chan, email) {
|
||||||
|
Ok(()) if email.is_empty() => ctx.notice(me, from.uid, format!("Contact email for \x02{chan}\x02 cleared.")),
|
||||||
|
Ok(()) => ctx.notice(me, from.uid, format!("Contact email for \x02{chan}\x02 updated.")),
|
||||||
|
Err(_) => ctx.notice(me, from.uid, "Sorry, that didn't work. Please try again in a moment."),
|
||||||
|
}
|
||||||
|
}
|
||||||
Some("SIGNKICK") => toggle(me, from, ctx, db, chan, ChanSetting::SignKick, args.get(3).copied()),
|
Some("SIGNKICK") => toggle(me, from, ctx, db, chan, ChanSetting::SignKick, args.get(3).copied()),
|
||||||
Some("PRIVATE") => toggle(me, from, ctx, db, chan, ChanSetting::Private, args.get(3).copied()),
|
Some("PRIVATE") => toggle(me, from, ctx, db, chan, ChanSetting::Private, args.get(3).copied()),
|
||||||
Some("PEACE") => toggle(me, from, ctx, db, chan, ChanSetting::Peace, args.get(3).copied()),
|
Some("PEACE") => toggle(me, from, ctx, db, chan, ChanSetting::Peace, args.get(3).copied()),
|
||||||
|
|
@ -80,7 +88,7 @@ pub fn handle(me: &str, from: &Sender, args: &[&str], ctx: &mut ServiceCtx, db:
|
||||||
Some("AUTOOP") => toggle(me, from, ctx, db, chan, ChanSetting::AutoOp, args.get(3).copied()),
|
Some("AUTOOP") => toggle(me, from, ctx, db, chan, ChanSetting::AutoOp, args.get(3).copied()),
|
||||||
Some("KEEPTOPIC") => toggle(me, from, ctx, db, chan, ChanSetting::KeepTopic, 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()),
|
Some("TOPICLOCK") => toggle(me, from, ctx, db, chan, ChanSetting::TopicLock, args.get(3).copied()),
|
||||||
_ => ctx.notice(me, from.uid, "Syntax: SET <#channel> FOUNDER <account> | SUCCESSOR <account>|OFF | DESC <text> | URL [address] | SIGNKICK {ON|OFF} | PRIVATE {ON|OFF} | PEACE {ON|OFF} | SECUREOPS {ON|OFF} | RESTRICTED {ON|OFF} | AUTOOP {ON|OFF} | KEEPTOPIC {ON|OFF} | TOPICLOCK {ON|OFF}"),
|
_ => ctx.notice(me, from.uid, "Syntax: SET <#channel> FOUNDER <account> | SUCCESSOR <account>|OFF | DESC <text> | URL [address] | EMAIL [address] | SIGNKICK {ON|OFF} | PRIVATE {ON|OFF} | PEACE {ON|OFF} | SECUREOPS {ON|OFF} | RESTRICTED {ON|OFF} | AUTOOP {ON|OFF} | KEEPTOPIC {ON|OFF} | TOPICLOCK {ON|OFF}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ impl Db {
|
||||||
self.log
|
self.log
|
||||||
.append(Event::ChannelRegistered { name: name.to_string(), founder: founder.to_string(), ts })
|
.append(Event::ChannelRegistered { name: name.to_string(), founder: founder.to_string(), ts })
|
||||||
.map_err(|_| ChanError::Internal)?;
|
.map_err(|_| ChanError::Internal)?;
|
||||||
self.channels.insert(k, ChannelInfo { name: name.to_string(), founder: founder.to_string(), ts, lock_on: String::new(), lock_off: String::new(), access: Vec::new(), akick: Vec::new(), successor: None, desc: String::new(), entrymsg: String::new(), url: String::new(), settings: ChanSettings::default(), topic: String::new(), suspension: None, assigned_bot: None , kickers: KickerSettings::default() , badwords: Vec::new(), badwords_rev: 0 , triggers: Vec::new(), triggers_rev: 0, last_used: ts, noexpire: false, expiry_warned: false, oper_note: None });
|
self.channels.insert(k, ChannelInfo { name: name.to_string(), founder: founder.to_string(), ts, lock_on: String::new(), lock_off: String::new(), access: Vec::new(), akick: Vec::new(), successor: None, desc: String::new(), entrymsg: String::new(), url: String::new(), email: String::new(), settings: ChanSettings::default(), topic: String::new(), suspension: None, assigned_bot: None , kickers: KickerSettings::default() , badwords: Vec::new(), badwords_rev: 0 , triggers: Vec::new(), triggers_rev: 0, last_used: ts, noexpire: false, expiry_warned: false, oper_note: None });
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,6 +199,18 @@ impl Db {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn set_channel_email(&mut self, channel: &str, email: &str) -> Result<(), ChanError> {
|
||||||
|
let k = key(channel);
|
||||||
|
if !self.channels.contains_key(&k) {
|
||||||
|
return Err(ChanError::NoChannel);
|
||||||
|
}
|
||||||
|
self.log
|
||||||
|
.append(Event::ChannelEmailSet { channel: channel.to_string(), email: email.to_string() })
|
||||||
|
.map_err(|_| ChanError::Internal)?;
|
||||||
|
self.channels.get_mut(&k).unwrap().email = email.to_string();
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Turn one ChanServ SET option on or off for a channel.
|
/// Turn one ChanServ SET option on or off for a channel.
|
||||||
pub fn set_channel_setting(&mut self, channel: &str, setting: ChanSetting, on: bool) -> Result<(), ChanError> {
|
pub fn set_channel_setting(&mut self, channel: &str, setting: ChanSetting, on: bool) -> Result<(), ChanError> {
|
||||||
let k = key(channel);
|
let k = key(channel);
|
||||||
|
|
|
||||||
|
|
@ -49,6 +49,7 @@ pub enum Event {
|
||||||
ChannelDescSet { channel: String, desc: String },
|
ChannelDescSet { channel: String, desc: String },
|
||||||
ChannelEntryMsgSet { channel: String, msg: String },
|
ChannelEntryMsgSet { channel: String, msg: String },
|
||||||
ChannelUrlSet { channel: String, url: String },
|
ChannelUrlSet { channel: String, url: String },
|
||||||
|
ChannelEmailSet { channel: String, email: String },
|
||||||
ChannelSettingsSet { channel: String, settings: ChanSettings },
|
ChannelSettingsSet { channel: String, settings: ChanSettings },
|
||||||
ChannelKickerSet { channel: String, kickers: KickerSettings },
|
ChannelKickerSet { channel: String, kickers: KickerSettings },
|
||||||
ChannelBadwordsSet { channel: String, badwords: Vec<String> },
|
ChannelBadwordsSet { channel: String, badwords: Vec<String> },
|
||||||
|
|
@ -210,6 +211,7 @@ impl Event {
|
||||||
| Event::ChannelDescSet { .. }
|
| Event::ChannelDescSet { .. }
|
||||||
| Event::ChannelEntryMsgSet { .. }
|
| Event::ChannelEntryMsgSet { .. }
|
||||||
| Event::ChannelUrlSet { .. }
|
| Event::ChannelUrlSet { .. }
|
||||||
|
| Event::ChannelEmailSet { .. }
|
||||||
| Event::ChannelSettingsSet { .. }
|
| Event::ChannelSettingsSet { .. }
|
||||||
| Event::ChannelKickerSet { .. }
|
| Event::ChannelKickerSet { .. }
|
||||||
| Event::ChannelBadwordsSet { .. }
|
| Event::ChannelBadwordsSet { .. }
|
||||||
|
|
@ -395,7 +397,7 @@ pub(crate) fn apply(accounts: &mut HashMap<String, Account>, channels: &mut Hash
|
||||||
grouped.remove(&key(&nick));
|
grouped.remove(&key(&nick));
|
||||||
}
|
}
|
||||||
Event::ChannelRegistered { name, founder, ts } => {
|
Event::ChannelRegistered { name, founder, ts } => {
|
||||||
channels.insert(key(&name), ChannelInfo { name, founder, ts, lock_on: String::new(), lock_off: String::new(), access: Vec::new(), akick: Vec::new(), successor: None, desc: String::new(), entrymsg: String::new(), url: String::new(), settings: ChanSettings::default(), topic: String::new(), suspension: None, assigned_bot: None , kickers: KickerSettings::default() , badwords: Vec::new(), badwords_rev: 0 , triggers: Vec::new(), triggers_rev: 0, last_used: ts, noexpire: false, expiry_warned: false, oper_note: None });
|
channels.insert(key(&name), ChannelInfo { name, founder, ts, lock_on: String::new(), lock_off: String::new(), access: Vec::new(), akick: Vec::new(), successor: None, desc: String::new(), entrymsg: String::new(), url: String::new(), email: String::new(), settings: ChanSettings::default(), topic: String::new(), suspension: None, assigned_bot: None , kickers: KickerSettings::default() , badwords: Vec::new(), badwords_rev: 0 , triggers: Vec::new(), triggers_rev: 0, last_used: ts, noexpire: false, expiry_warned: false, oper_note: None });
|
||||||
}
|
}
|
||||||
Event::ChannelDropped { name } => {
|
Event::ChannelDropped { name } => {
|
||||||
channels.remove(&key(&name));
|
channels.remove(&key(&name));
|
||||||
|
|
@ -448,6 +450,11 @@ pub(crate) fn apply(accounts: &mut HashMap<String, Account>, channels: &mut Hash
|
||||||
c.url = url;
|
c.url = url;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Event::ChannelEmailSet { channel, email } => {
|
||||||
|
if let Some(c) = channels.get_mut(&key(&channel)) {
|
||||||
|
c.email = email;
|
||||||
|
}
|
||||||
|
}
|
||||||
Event::ChannelSettingsSet { channel, settings } => {
|
Event::ChannelSettingsSet { channel, settings } => {
|
||||||
if let Some(c) = channels.get_mut(&key(&channel)) {
|
if let Some(c) = channels.get_mut(&key(&channel)) {
|
||||||
c.settings = settings;
|
c.settings = settings;
|
||||||
|
|
|
||||||
|
|
@ -422,6 +422,9 @@ pub struct ChannelInfo {
|
||||||
// Channel homepage URL, shown in INFO (empty = none).
|
// Channel homepage URL, shown in INFO (empty = none).
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub url: String,
|
pub url: String,
|
||||||
|
// Channel contact email, shown in INFO (empty = none).
|
||||||
|
#[serde(default)]
|
||||||
|
pub email: String,
|
||||||
// On/off options set via ChanServ SET.
|
// On/off options set via ChanServ SET.
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub settings: ChanSettings,
|
pub settings: ChanSettings,
|
||||||
|
|
|
||||||
|
|
@ -377,6 +377,9 @@ impl Store for Db {
|
||||||
fn set_url(&mut self, channel: &str, url: &str) -> Result<(), ChanError> {
|
fn set_url(&mut self, channel: &str, url: &str) -> Result<(), ChanError> {
|
||||||
Db::set_url(self, channel, url)
|
Db::set_url(self, channel, url)
|
||||||
}
|
}
|
||||||
|
fn set_channel_email(&mut self, channel: &str, email: &str) -> Result<(), ChanError> {
|
||||||
|
Db::set_channel_email(self, channel, email)
|
||||||
|
}
|
||||||
fn set_channel_setting(&mut self, channel: &str, setting: ChanSetting, on: bool) -> Result<(), ChanError> {
|
fn set_channel_setting(&mut self, channel: &str, setting: ChanSetting, on: bool) -> Result<(), ChanError> {
|
||||||
Db::set_channel_setting(self, channel, setting, on)
|
Db::set_channel_setting(self, channel, setting, on)
|
||||||
}
|
}
|
||||||
|
|
@ -559,6 +562,7 @@ fn channel_view(c: &ChannelInfo) -> ChannelView {
|
||||||
desc: c.desc.clone(),
|
desc: c.desc.clone(),
|
||||||
entrymsg: c.entrymsg.clone(),
|
entrymsg: c.entrymsg.clone(),
|
||||||
url: c.url.clone(),
|
url: c.url.clone(),
|
||||||
|
email: c.email.clone(),
|
||||||
signkick: c.settings.signkick,
|
signkick: c.settings.signkick,
|
||||||
private: c.settings.private,
|
private: c.settings.private,
|
||||||
peace: c.settings.peace,
|
peace: c.settings.peace,
|
||||||
|
|
|
||||||
|
|
@ -1186,7 +1186,7 @@ fn audit_summary(event: &db::Event) -> Option<String> {
|
||||||
AjoinAdded { .. } | AjoinRemoved { .. } | AccountGreetSet { .. } | AccountAutoOpSet { .. } | AccountKillSet { .. } | AccountHideStatusSet { .. } | VhostRequested { .. }
|
AjoinAdded { .. } | AjoinRemoved { .. } | AccountGreetSet { .. } | AccountAutoOpSet { .. } | AccountKillSet { .. } | AccountHideStatusSet { .. } | VhostRequested { .. }
|
||||||
| VhostRequestCleared { .. } | MemoSent { .. } | MemoRead { .. } | MemoDeleted { .. }
|
| VhostRequestCleared { .. } | MemoSent { .. } | MemoRead { .. } | MemoDeleted { .. }
|
||||||
| MemoIgnoreAdd { .. } | MemoIgnoreDel { .. } | MemoPrefsSet { .. }
|
| MemoIgnoreAdd { .. } | MemoIgnoreDel { .. } | MemoPrefsSet { .. }
|
||||||
| ChannelMlock { .. } | ChannelDescSet { .. } | ChannelEntryMsgSet { .. } | ChannelUrlSet { .. } | ChannelSettingsSet { .. }
|
| ChannelMlock { .. } | ChannelDescSet { .. } | ChannelEntryMsgSet { .. } | ChannelUrlSet { .. } | ChannelEmailSet { .. } | ChannelSettingsSet { .. }
|
||||||
| ChannelKickerSet { .. } | ChannelBadwordsSet { .. } | ChannelTriggersSet { .. }
|
| ChannelKickerSet { .. } | ChannelBadwordsSet { .. } | ChannelTriggersSet { .. }
|
||||||
| ChannelTopicSet { .. } | AccountSeen { .. } | ChannelUsed { .. }
|
| ChannelTopicSet { .. } | AccountSeen { .. } | ChannelUsed { .. }
|
||||||
| AccountExpiryWarned { .. } | ChannelExpiryWarned { .. } => return None,
|
| AccountExpiryWarned { .. } | ChannelExpiryWarned { .. } => return None,
|
||||||
|
|
|
||||||
|
|
@ -4204,6 +4204,12 @@
|
||||||
assert!(notice(&to_cs(&mut e, "000AAAAAB", "SET #c URL"), "cleared"));
|
assert!(notice(&to_cs(&mut e, "000AAAAAB", "SET #c URL"), "cleared"));
|
||||||
assert!(!notice(&to_cs(&mut e, "000AAAAAB", "INFO #c"), "example.org"), "cleared URL no longer shows");
|
assert!(!notice(&to_cs(&mut e, "000AAAAAB", "INFO #c"), "example.org"), "cleared URL no longer shows");
|
||||||
|
|
||||||
|
// Contact email is stored, shows in INFO, and clears when set empty.
|
||||||
|
assert!(notice(&to_cs(&mut e, "000AAAAAB", "SET #c EMAIL staff@example.org"), "updated"));
|
||||||
|
assert!(notice(&to_cs(&mut e, "000AAAAAB", "INFO #c"), "staff@example.org"));
|
||||||
|
assert!(notice(&to_cs(&mut e, "000AAAAAB", "SET #c EMAIL"), "cleared"));
|
||||||
|
assert!(!notice(&to_cs(&mut e, "000AAAAAB", "INFO #c"), "staff@example.org"), "cleared email no longer shows");
|
||||||
|
|
||||||
// Transfer to a non-account is refused.
|
// Transfer to a non-account is refused.
|
||||||
assert!(notice(&to_cs(&mut e, "000AAAAAB", "SET #c FOUNDER nobody"), "isn't a registered account"));
|
assert!(notice(&to_cs(&mut e, "000AAAAAB", "SET #c FOUNDER nobody"), "isn't a registered account"));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,6 +152,7 @@ fn to_wire(entry: &LogEntry) -> Option<ReplicationEvent> {
|
||||||
| Event::ChannelAkickDel { .. }
|
| Event::ChannelAkickDel { .. }
|
||||||
| Event::ChannelEntryMsgSet { .. }
|
| Event::ChannelEntryMsgSet { .. }
|
||||||
| Event::ChannelUrlSet { .. }
|
| Event::ChannelUrlSet { .. }
|
||||||
|
| Event::ChannelEmailSet { .. }
|
||||||
| Event::ChannelSuccessorSet { .. }
|
| Event::ChannelSuccessorSet { .. }
|
||||||
| Event::ChannelSettingsSet { .. }
|
| Event::ChannelSettingsSet { .. }
|
||||||
| Event::ChannelKickerSet { .. }
|
| Event::ChannelKickerSet { .. }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue