From 4fcbbbe4fbc137841b47c8e2372477b85649270a Mon Sep 17 00:00:00 2001 From: Adam Date: Sat, 17 Dec 2016 21:44:22 -0500 Subject: Split ircdproto send functions out into separate services This makes it easier to see which send functions a protocol module implements as they are all explicitly registered by the module, and avoids the problem of subtly breaking other protocol modules when using inheritance. Also split the old "core" send implementations out into a module, and the TS6 ID generator --- modules/protocol/unreal.cpp | 480 ++++++++++++++++++++++++-------------------- 1 file changed, 267 insertions(+), 213 deletions(-) (limited to 'modules/protocol/unreal.cpp') diff --git a/modules/protocol/unreal.cpp b/modules/protocol/unreal.cpp index 4a4a0c4d0..f319268b7 100644 --- a/modules/protocol/unreal.cpp +++ b/modules/protocol/unreal.cpp @@ -17,7 +17,7 @@ * along with this program; if not, see see . */ -/* Dependencies: anope_protocol.rfc1459 */ +/* Dependencies: anope_protocol.rfc1459,anope_protocol.bahamut */ #include "module.h" #include "modules/chanserv/mode.h" @@ -25,75 +25,11 @@ #include "modules/operserv/stats.h" #include "modules/protocol/rfc1459.h" #include "modules/protocol/unreal.h" +#include "modules/protocol/bahamut.h" static Anope::string UplinkSID; -unreal::Proto::Proto(Module *creator) : IRCDProto(creator, "UnrealIRCd 4") -{ - DefaultPseudoclientModes = "+Soiq"; - CanSVSNick = true; - CanSVSJoin = true; - CanSetVHost = true; - CanSetVIdent = true; - CanSNLine = true; - CanSQLine = true; - CanSZLine = true; - CanSVSHold = true; - CanCertFP = true; - RequiresID = true; - MaxModes = 12; -} - -/* SVSNOOP */ -void unreal::Proto::SendSVSNOOP(Server *server, bool set) -{ - Uplink::Send("SVSNOOP", server->GetSID(), set ? "+" : "-"); -} - -void unreal::Proto::SendAkillDel(XLine *x) -{ - if (x->IsRegex() || x->HasNickOrReal()) - return; - - /* ZLine if we can instead */ - if (x->GetUser() == "*") - { - cidr a(x->GetHost()); - if (a.valid()) - { - IRCD->SendSZLineDel(x); - return; - } - } - - Uplink::Send("TKL", "-", "G", x->GetUser(), x->GetHost(), x->GetBy()); -} - -void unreal::Proto::SendTopic(const MessageSource &source, Channel *c) -{ - Uplink::Send(source, "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic); -} - -void unreal::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg); -} - -void unreal::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg); -} - -void unreal::Proto::SendVhostDel(User *u) -{ - ServiceBot *HostServ = Config->GetClient("HostServ"); - u->RemoveMode(HostServ, "CLOAK"); - u->RemoveMode(HostServ, "VHOST"); - ModeManager::ProcessModes(); - u->SetMode(HostServ, "CLOAK"); -} - -void unreal::Proto::SendAkill(User *u, XLine *x) +void unreal::senders::Akill::Send(User* u, XLine* x) { if (x->IsRegex() || x->HasNickOrReal()) { @@ -102,7 +38,7 @@ void unreal::Proto::SendAkill(User *u, XLine *x) /* No user (this akill was just added), and contains nick and/or realname. Find users that match and ban them */ for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) if (x->GetManager()->Check(it->second, x)) - this->SendAkill(it->second, x); + this->Send(it->second, x); return; } @@ -131,7 +67,7 @@ void unreal::Proto::SendAkill(User *u, XLine *x) cidr a(x->GetHost()); if (a.valid()) { - IRCD->SendSZLine(u, x); + IRCD->Send(u, x); return; } } @@ -143,37 +79,46 @@ void unreal::Proto::SendAkill(User *u, XLine *x) Uplink::Send("TKL", "+", "G", x->GetUser(), x->GetHost(), x->GetBy(), Anope::CurTime + timeleft, x->GetCreated(), x->GetReason()); } -void unreal::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) +void unreal::senders::AkillDel::Send(XLine* x) { - Uplink::Send(source, "SVSKILL", user->GetUID(), buf); - user->KillInternal(source, buf); -} + if (x->IsRegex() || x->HasNickOrReal()) + return; -void unreal::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf) -{ - IRCMessage message(source, "SVS2MODE", u->GetUID()); - message.TokenizeAndPush(buf); - Uplink::SendMessage(message); -} + /* ZLine if we can instead */ + if (x->GetUser() == "*") + { + cidr a(x->GetHost()); + if (a.valid()) + { + IRCD->Send(x); + return; + } + } -void unreal::Proto::SendClientIntroduction(User *u) -{ - Anope::string modes = "+" + u->GetModes(); - Uplink::Send("UID", u->nick, 1, u->timestamp, u->GetIdent(), u->host, u->GetUID(), "*", modes, !u->vhost.empty() ? u->vhost : "*", !u->chost.empty() ? u->chost : "*", "*", u->realname); + Uplink::Send("TKL", "-", "G", x->GetUser(), x->GetHost(), x->GetBy()); } -/* SERVER name hop descript */ -/* Unreal 3.2 actually sends some info about itself in the descript area */ -void unreal::Proto::SendServer(Server *server) +void unreal::senders::MessageChannel::Send(Channel* c) { - if (!server->GetSID().empty() && server == Me) - Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription()); + /* Unreal does not support updating a channels TS without actually joining a user, + * so we will join and part us now + */ + ServiceBot *bi = c->ci->WhoSends(); + if (!bi) + ; + else if (c->FindUser(bi) == NULL) + { + bi->Join(c); + bi->Part(c); + } else - Uplink::Send("SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription()); + { + bi->Part(c); + bi->Join(c); + } } -/* JOIN */ -void unreal::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status) +void unreal::senders::Join::Send(User* user, Channel* c, const ChannelStatus* status) { Uplink::Send(Me, "SJOIN", c->creation_time, c->name, user->GetUID()); if (status) @@ -196,83 +141,87 @@ void unreal::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status } } -/* unsqline -*/ -void unreal::Proto::SendSQLineDel(XLine *x) +void unreal::senders::Kill::Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) { - Uplink::Send("UNSQLINE", x->GetMask()); + Uplink::Send(source, "SVSKILL", target, reason); } -/* SQLINE */ -/* -** - Unreal will translate this to TKL for us -** -*/ -void unreal::Proto::SendSQLine(User *, XLine *x) +void unreal::senders::Kill::Send(const MessageSource &source, User *user, const Anope::string &reason) { - Uplink::Send("SQLINE", x->GetMask(), x->GetReason()); + Uplink::Send(source, "SVSKILL", user->GetUID(), reason); + user->KillInternal(source, reason); } -/* Functions that use serval cmd functions */ +void unreal::senders::Login::Send(User *u, NickServ::Nick *na) +{ + /* 3.2.10.4+ treats users logged in with accounts as fully registered, even if -r, so we can not set this here. Just use the timestamp. */ + if (Servers::Capab.count("ESVID") > 0 && !na->GetAccount()->IsUnconfirmed()) + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", na->GetAccount()->GetDisplay()); + else + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon); +} -void unreal::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) +void unreal::senders::Logout::Send(User *u) { - if (!vIdent.empty()) - Uplink::Send(Me, "CHGIDENT", u->GetUID(), vIdent); - if (!vhost.empty()) - Uplink::Send(Me, "CHGHOST", u->GetUID(), vhost); + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0"); } -void unreal::Proto::SendConnect() +void unreal::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes) { - /* - NICKv2 = Nick Version 2 - VHP = Sends hidden host - UMODE2 = sends UMODE2 on user modes - NICKIP = Sends IP on NICK - SJ3 = Supports SJOIN - NOQUIT = No Quit - TKLEXT = Extended TKL we don't use it but best to have it - MLOCK = Supports the MLOCK server command - VL = Version Info - SID = SID/UID mode - */ - Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password); - Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID"); - Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort()); - Uplink::Send("PROTOCTL", "SID=" + Me->GetSID()); - SendServer(Me); + IRCMessage message(source, "SVS2MODE", user->GetUID()); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); } -/* SVSHOLD - set */ -void unreal::Proto::SendSVSHold(const Anope::string &nick, time_t t) +void unreal::senders::NickIntroduction::Send(User *user) { - Uplink::Send("TKL", "+", "Q", "H", nick, Me->GetName(), Anope::CurTime + t, Anope::CurTime, "Being held for registered user"); + Anope::string modes = "+" + user->GetModes(); + Uplink::Send("UID", user->nick, 1, user->timestamp, user->GetIdent(), user->host, user->GetUID(), "*", modes, !user->vhost.empty() ? user->vhost : "*", !user->chost.empty() ? user->chost : "*", "*", user->realname); } -/* SVSHOLD - release */ -void unreal::Proto::SendSVSHoldDel(const Anope::string &nick) +void unreal::senders::SASL::Send(const ::SASL::Message& message) { - Uplink::Send("TKL", "-", "Q", "*", nick, Me->GetName()); + size_t p = message.target.find('!'); + if (p == Anope::string::npos) + return; + + if (!message.ext.empty()) + Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data, message.ext); + else + Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data); } -/* UNSGLINE */ -/* - * SVSNLINE - :realname mask -*/ -void unreal::Proto::SendSGLineDel(XLine *x) +void unreal::senders::MessageServer::Send(Server* server) +{ + Uplink::Send(Me, "SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription()); +} + +void unreal::senders::SGLine::Send(User*, XLine* x) +{ + /* + * SVSNLINE + reason_where_is_space :realname mask with spaces + */ + Anope::string edited_reason = x->GetReason(); + edited_reason = edited_reason.replace_all_cs(" ", "_"); + Uplink::Send("SVSNLINE", "+", edited_reason, x->GetMask()); +} + +void unreal::senders::SGLineDel::Send(XLine* x) { Uplink::Send("SVSNLINE", "-", x->GetMask()); } -/* UNSZLINE */ -void unreal::Proto::SendSZLineDel(XLine *x) +void unreal::senders::SQLine::Send(User*, XLine* x) { - Uplink::Send("TKL", "-", "Z", "*", x->GetHost(), x->GetBy()); + Uplink::Send("SQLINE", x->GetMask(), x->GetReason()); } -/* SZLINE */ -void unreal::Proto::SendSZLine(User *, XLine *x) +void unreal::senders::SQLineDel::Send(XLine* x) +{ + Uplink::Send("UNSQLINE", x->GetMask()); +} + +void unreal::senders::SZLine::Send(User*, XLine* x) { // Calculate the time left before this would expire, capping it at 2 days time_t timeleft = x->GetExpires() - Anope::CurTime; @@ -281,15 +230,19 @@ void unreal::Proto::SendSZLine(User *, XLine *x) Uplink::Send("TKL", "+", "Z", "*", x->GetHost(), x->GetBy(), Anope::CurTime + timeleft, x->GetCreated(), x->GetReason()); } -/* SGLINE */ -/* - * SVSNLINE + reason_where_is_space :realname mask with spaces -*/ -void unreal::Proto::SendSGLine(User *, XLine *x) +void unreal::senders::SZLineDel::Send(XLine* x) { - Anope::string edited_reason = x->GetReason(); - edited_reason = edited_reason.replace_all_cs(" ", "_"); - Uplink::Send("SVSNLINE", "+", edited_reason, x->GetMask()); + Uplink::Send("TKL", "-", "Z", "*", x->GetHost(), x->GetBy()); +} + +void unreal::senders::SVSHold::Send(const Anope::string& nick, time_t t) +{ + Uplink::Send("TKL", "+", "Q", "H", nick, Me->GetName(), Anope::CurTime + t, Anope::CurTime, "Being held for registered user"); +} + +void unreal::senders::SVSHoldDel::Send(const Anope::string& nick) +{ + Uplink::Send("TKL", "-", "Q", "*", nick, Me->GetName()); } /* svsjoin @@ -298,105 +251,118 @@ void unreal::Proto::SendSGLine(User *, XLine *x) parv[2] - channel to join parv[3] - (optional) channel key(s) */ -void unreal::Proto::SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) +void unreal::senders::SVSJoin::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& key) { - if (!param.empty()) - Uplink::Send(source, "SVSJOIN", user->GetUID(), chan, param); + if (!key.empty()) + Uplink::Send(source, "SVSJOIN", user->GetUID(), chan, key); else Uplink::Send(source, "SVSJOIN", user->GetUID(), chan); } -void unreal::Proto::SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) +void unreal::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost) { - if (!param.empty()) - Uplink::Send(source, "SVSPART", user->GetUID(), chan, param); + size_t p = uid.find('!'); + if (p == Anope::string::npos) + return; + Uplink::Send(Me, "SVSLOGIN", uid.substr(0, p), uid, acc); +} + +void unreal::senders::SVSPart::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& reason) +{ + if (!reason.empty()) + Uplink::Send(source, "SVSPART", user->GetUID(), chan, reason); else Uplink::Send(source, "SVSPART", user->GetUID(), chan); } -void unreal::Proto::SendSWhois(const MessageSource &source, const Anope::string &who, const Anope::string &mask) +void unreal::senders::SWhois::Send(const MessageSource& source, User *user, const Anope::string& swhois) { - Uplink::Send(source, "SWHOIS", who, mask); + Uplink::Send(source, "SWHOIS", user->GetUID(), swhois); } -void unreal::Proto::SendEOB() +void unreal::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) { - Uplink::Send(Me, "EOS"); + Uplink::Send(source, "TOPIC", channel->name, topic_setter, topic_ts, topic); } -bool unreal::Proto::IsNickValid(const Anope::string &nick) +void unreal::senders::VhostDel::Send(User* u) { - if (nick.equals_ci("ircd") || nick.equals_ci("irc")) - return false; - - return IRCDProto::IsNickValid(nick); + ServiceBot *HostServ = Config->GetClient("HostServ"); + u->RemoveMode(HostServ, "CLOAK"); + u->RemoveMode(HostServ, "VHOST"); + ModeManager::ProcessModes(); + u->SetMode(HostServ, "CLOAK"); } -bool unreal::Proto::IsChannelValid(const Anope::string &chan) +void unreal::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost) { - if (chan.find(':') != Anope::string::npos) - return false; - - return IRCDProto::IsChannelValid(chan); + if (!vident.empty()) + Uplink::Send(Me, "CHGIDENT", u->GetUID(), vident); + if (!vhost.empty()) + Uplink::Send(Me, "CHGHOST", u->GetUID(), vhost); } -bool unreal::Proto:: IsExtbanValid(const Anope::string &mask) +unreal::Proto::Proto(Module *creator) : IRCDProto(creator, "UnrealIRCd 4") { - return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':'; + DefaultPseudoclientModes = "+Soiq"; + CanSVSNick = true; + CanSVSJoin = true; + CanSetVHost = true; + CanSetVIdent = true; + CanSNLine = true; + CanSQLine = true; + CanSZLine = true; + CanSVSHold = true; + CanCertFP = true; + RequiresID = true; + MaxModes = 12; } -void unreal::Proto::SendLogin(User *u, NickServ::Nick *na) +void unreal::Proto::Handshake() { - /* 3.2.10.4+ treats users logged in with accounts as fully registered, even if -r, so we can not set this here. Just use the timestamp. */ - if (Servers::Capab.count("ESVID") > 0 && !na->GetAccount()->IsUnconfirmed()) - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", na->GetAccount()->GetDisplay()); - else - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon); + /* + NICKv2 = Nick Version 2 + VHP = Sends hidden host + UMODE2 = sends UMODE2 on user modes + NICKIP = Sends IP on NICK + SJ3 = Supports SJOIN + NOQUIT = No Quit + TKLEXT = Extended TKL we don't use it but best to have it + MLOCK = Supports the MLOCK server command + VL = Version Info + SID = SID/UID mode + */ + Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password); + Uplink::Send("PROTOCTL", "NICKv2", "VHP", "UMODE2", "NICKIP", "SJOIN", "SJOIN2", "SJ3", "NOQUIT", "TKLEXT", "MLOCK", "SID"); + Uplink::Send("PROTOCTL", "EAUTH=" + Me->GetName() + ",,,Anope-" + Anope::VersionShort()); + Uplink::Send("PROTOCTL", "SID=" + Me->GetSID()); + Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription()); } -void unreal::Proto::SendLogout(User *u) +void unreal::Proto::SendEOB() { - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 0"); + Uplink::Send(Me, "EOS"); } -void unreal::Proto::SendChannel(Channel *c) +bool unreal::Proto::IsNickValid(const Anope::string &nick) { - /* Unreal does not support updating a channels TS without actually joining a user, - * so we will join and part us now - */ - ServiceBot *bi = c->ci->WhoSends(); - if (!bi) - ; - else if (c->FindUser(bi) == NULL) - { - bi->Join(c); - bi->Part(c); - } - else - { - bi->Part(c); - bi->Join(c); - } + if (nick.equals_ci("ircd") || nick.equals_ci("irc")) + return false; + + return IRCDProto::IsNickValid(nick); } -void unreal::Proto::SendSASLMessage(const ::SASL::Message &message) +bool unreal::Proto::IsChannelValid(const Anope::string &chan) { - size_t p = message.target.find('!'); - if (p == Anope::string::npos) - return; + if (chan.find(':') != Anope::string::npos) + return false; - if (!message.ext.empty()) - Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data, message.ext); - else - Uplink::Send(ServiceBot::Find(message.source), "SASL", message.target.substr(0, p), message.target, message.type, message.data); + return IRCDProto::IsChannelValid(chan); } -void unreal::Proto::SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) +bool unreal::Proto:: IsExtbanValid(const Anope::string &mask) { - size_t p = uid.find('!'); - if (p == Anope::string::npos) - return; - Uplink::Send(Me, "SVSLOGIN", uid.substr(0, p), uid, acc); + return mask.length() >= 4 && mask[0] == '~' && mask[2] == ':'; } bool unreal::Proto::IsIdentValid(const Anope::string &ident) @@ -889,7 +855,7 @@ void unreal::ServerMessage::Run(MessageSource &source, const std::vectorSendPing(Me->GetName(), params[0]); + IRCD->Send(Me->GetName(), params[0]); } void unreal::SID::Run(MessageSource &source, const std::vector ¶ms) @@ -904,7 +870,7 @@ void unreal::SID::Run(MessageSource &source, const std::vector &p new Server(source.GetServer(), params[0], hops, params[3], params[2]); - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send(Me->GetName(), params[0]); } void unreal::SJoin::Run(MessageSource &source, const std::vector ¶ms) @@ -1156,6 +1122,48 @@ class ProtoUnreal : public Module unreal::UID message_uid; unreal::Umode2 message_umode2; + rfc1459::senders::GlobalNotice sender_global_notice; + rfc1459::senders::GlobalPrivmsg sender_global_privmsg; + rfc1459::senders::Invite sender_invite; + rfc1459::senders::Kick sender_kick; + rfc1459::senders::ModeChannel sender_mode_chan; + rfc1459::senders::NickChange sender_nickchange; + rfc1459::senders::Notice sender_notice; + rfc1459::senders::Part sender_part; + rfc1459::senders::Ping sender_ping; + rfc1459::senders::Pong sender_pong; + rfc1459::senders::Privmsg sender_privmsg; + rfc1459::senders::Quit sender_quit; + rfc1459::senders::SQuit sender_squit; + + bahamut::senders::NOOP sender_noop; + bahamut::senders::SVSNick sender_svsnick; + bahamut::senders::Wallops sender_wallops; + + unreal::senders::Akill sender_akill; + unreal::senders::AkillDel sender_akill_del; + unreal::senders::MessageChannel sender_channel; + unreal::senders::Join sender_join; + unreal::senders::Kill sender_svskill; + unreal::senders::Login sender_login; + unreal::senders::Logout sender_logout; + unreal::senders::ModeUser sender_mode_user; + unreal::senders::NickIntroduction sender_nickintroduction; + unreal::senders::MessageServer sender_server; + unreal::senders::SASL sender_sasl; + unreal::senders::SGLine sender_sgline; + unreal::senders::SGLineDel sender_sgline_del; + unreal::senders::SQLine sender_sqline; + unreal::senders::SQLineDel sender_sqline_del; + unreal::senders::SVSHold sender_svshold; + unreal::senders::SVSHoldDel sender_svsholddel; + unreal::senders::SVSJoin sender_svsjoin; + unreal::senders::SVSPart sender_svspart; + unreal::senders::SWhois sender_swhois; + unreal::senders::Topic sender_topic; + unreal::senders::VhostDel sender_vhost_del; + unreal::senders::VhostSet sender_vhost_set; + bool use_server_side_mlock; public: @@ -1207,7 +1215,53 @@ class ProtoUnreal : public Module , message_topic(this) , message_uid(this) , message_umode2(this) + + , sender_akill(this) + , sender_akill_del(this) + , sender_channel(this) + , sender_global_notice(this) + , sender_global_privmsg(this) + , sender_invite(this) + , sender_join(this) + , sender_kick(this) + , sender_svskill(this) + , sender_login(this) + , sender_logout(this) + , sender_mode_chan(this) + , sender_mode_user(this) + , sender_nickchange(this) + , sender_nickintroduction(this) + , sender_noop(this) + , sender_notice(this) + , sender_part(this) + , sender_ping(this) + , sender_pong(this) + , sender_privmsg(this) + , sender_quit(this) + , sender_server(this) + , sender_sasl(this) + , sender_sgline(this) + , sender_sgline_del(this) + , sender_sqline(this) + , sender_sqline_del(this) + , sender_squit(this) + , sender_svshold(this) + , sender_svsholddel(this) + , sender_svsjoin(this) + , sender_svsnick(this) + , sender_svspart(this) + , sender_swhois(this) + , sender_topic(this) + , sender_vhost_del(this) + , sender_vhost_set(this) + , sender_wallops(this) + { + IRCD = &ircd_proto; + } + + ~ProtoUnreal() { + IRCD = nullptr; } void OnReload(Configuration::Conf *conf) override @@ -1251,7 +1305,7 @@ class ProtoUnreal : public Module { u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED")); if (Servers::Capab.count("ESVID") == 0) - IRCD->SendLogout(u); + sender_logout.Send(u); } void OnChannelSync(Channel *c) override -- cgit