diff options
Diffstat (limited to 'modules/protocol/bahamut.cpp')
-rw-r--r-- | modules/protocol/bahamut.cpp | 931 |
1 files changed, 495 insertions, 436 deletions
diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 9cd13182f..045045d03 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -1,348 +1,334 @@ -/* Bahamut functions +/* + * Anope IRC Services + * + * Copyright (C) 2003-2017 Anope Team <team@anope.org> * - * (C) 2003-2017 Anope Team - * Contact us at team@anope.org + * This file is part of Anope. Anope is free software; you can + * redistribute it and/or modify it under the terms of the GNU + * General Public License as published by the Free Software + * Foundation, version 2. * - * Please read COPYING and README for further details. + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. * - * Based on the original code of Epona by Lara. - * Based on the original code of Services by Andy Church. + * You should have received a copy of the GNU General Public License + * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ +/* Dependencies: anope_protocol.rfc1459 */ + #include "module.h" +#include "modules/protocol/rfc1459.h" +#include "modules/protocol/bahamut.h" -class ChannelModeFlood : public ChannelModeParam +void bahamut::senders::Akill::Send(User* u, XLine* x) { - public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } - - bool IsValid(Anope::string &value) const anope_override + if (x->IsRegex() || x->HasNickOrReal()) { - try + if (!u) { - Anope::string rest; - if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty()) - return true; + /* 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->Send(it->second, x); + return; } - catch (const ConvertException &) { } - return false; - } -}; + XLine *old = x; -class BahamutIRCdProto : public IRCDProto -{ - public: - BahamutIRCdProto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x") - { - DefaultPseudoclientModes = "+"; - CanSVSNick = true; - CanSNLine = true; - CanSQLine = true; - CanSQLineChannel = true; - CanSZLine = true; - CanSVSHold = true; - MaxModes = 60; + if (old->GetManager()->HasEntry("*@" + u->host)) + return; + + /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */ + x = Serialize::New<XLine *>(); + x->SetMask("*@" + u->host); + x->SetBy(old->GetBy()); + x->SetExpires(old->GetExpires()); + x->SetReason(old->GetReason()); + x->SetID(old->GetID()); + old->GetManager()->AddXLine(x); + + Anope::Logger.Bot("OperServ").Category("akill").Log(_("AKILL: Added an akill for {0} because {1}#{2} matches {3}"), + x->GetMask(), u->GetMask(), u->realname, old->GetMask()); } - void SendModeInternal(const MessageSource &source, const Channel *dest, const Anope::string &buf) anope_override + /* ZLine if we can instead */ + if (x->GetUser() == "*") { - if (Servers::Capab.count("TSMODE") > 0) + cidr a(x->GetHost()); + if (a.valid()) { - UplinkSocket::Message(source) << "MODE " << dest->name << " " << dest->creation_time << " " << buf; + IRCD->Send<messages::SZLine>(u, x); + return; } - else - IRCDProto::SendModeInternal(source, dest, buf); } - void SendModeInternal(const MessageSource &source, User *u, const Anope::string &buf) anope_override - { - UplinkSocket::Message(source) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf; - } + // Calculate the time left before this would expire, capping it at 2 days + time_t timeleft = x->GetExpires() - Anope::CurTime; + if (timeleft > 172800) + timeleft = 172800; - void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override - { - UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg; - } - - void SendGlobalPrivmsg(BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override - { - UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg; - } + Uplink::Send("AKILL", x->GetHost(), x->GetUser(), timeleft, x->GetBy(), Anope::CurTime, x->GetReason()); +} - /* SVSHOLD - set */ - void SendSVSHold(const Anope::string &nick, time_t time) anope_override - { - UplinkSocket::Message(Me) << "SVSHOLD " << nick << " " << time << " :Being held for registered user"; - } +void bahamut::senders::AkillDel::Send(XLine* x) +{ + if (x->IsRegex() || x->HasNickOrReal()) + return; - /* SVSHOLD - release */ - void SendSVSHoldDel(const Anope::string &nick) anope_override + /* ZLine if we can instead */ + if (x->GetUser() == "*") { - UplinkSocket::Message(Me) << "SVSHOLD " << nick << " 0"; + cidr a(x->GetHost()); + if (a.valid()) + { + IRCD->Send<messages::SZLineDel>(x); + return; + } } - /* SQLINE */ - void SendSQLine(User *, const XLine *x) anope_override - { - UplinkSocket::Message() << "SQLINE " << x->mask << " :" << x->GetReason(); - } + Uplink::Send("RAKILL", x->GetHost(), x->GetUser()); +} - /* UNSLINE */ - void SendSGLineDel(const XLine *x) anope_override - { - UplinkSocket::Message() << "UNSGLINE 0 :" << x->mask; - } +void bahamut::senders::MessageChannel::Send(Channel* c) +{ + Anope::string modes = c->GetModes(true, true); + if (modes.empty()) + modes = "+"; + Uplink::Send("SJOIN", c->creation_time, c->name, modes, ""); +} - /* UNSZLINE */ - void SendSZLineDel(const XLine *x) anope_override - { - /* this will likely fail so its only here for legacy */ - UplinkSocket::Message() << "UNSZLINE 0 " << x->GetHost(); - /* this is how we are supposed to deal with it */ - UplinkSocket::Message() << "RAKILL " << x->GetHost() << " *"; - } +void bahamut::senders::Join::Send(User* user, Channel* c, const ChannelStatus* status) +{ + Uplink::Send(user, "SJOIN", c->creation_time, c->name); - /* SZLINE */ - void SendSZLine(User *, const XLine *x) anope_override + if (status) { - // Calculate the time left before this would expire, capping it at 2 days - time_t timeleft = x->expires - Anope::CurTime; - if (timeleft > 172800 || !x->expires) - timeleft = 172800; - /* this will likely fail so its only here for legacy */ - UplinkSocket::Message() << "SZLINE " << x->GetHost() << " :" << x->GetReason(); - /* this is how we are supposed to deal with it */ - UplinkSocket::Message() << "AKILL " << x->GetHost() << " * " << timeleft << " " << x->by << " " << Anope::CurTime << " :" << x->GetReason(); - } + /* First save the channel status incase uc->Status == status */ + ChannelStatus cs = *status; + /* If the user is internally on the channel with flags, kill them so that + * the stacker will allow this. + */ + ChanUserContainer *uc = c->FindUser(user); + if (uc != NULL) + uc->status.Clear(); - /* SVSNOOP */ - void SendSVSNOOP(const Server *server, bool set) anope_override - { - UplinkSocket::Message() << "SVSNOOP " << server->GetName() << " " << (set ? "+" : "-"); - } + ServiceBot *setter = ServiceBot::Find(user->GetUID()); + for (size_t i = 0; i < cs.Modes().length(); ++i) + c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); - /* SGLINE */ - void SendSGLine(User *, const XLine *x) anope_override - { - UplinkSocket::Message() << "SGLINE " << x->mask.length() << " :" << x->mask << ":" << x->GetReason(); + if (uc != NULL) + uc->status = cs; } +} - /* RAKILL */ - void SendAkillDel(const XLine *x) anope_override - { - 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; - } - } +void bahamut::senders::Kill::Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) +{ + Uplink::Send(source, "SVSKILL", target, reason); +} - UplinkSocket::Message() << "RAKILL " << x->GetHost() << " " << x->GetUser(); - } +/* + Note: if the stamp is null 0, the below usage is correct of Bahamut +*/ +void bahamut::senders::Kill::Send(const MessageSource &source, User *user, const Anope::string &reason) +{ + Uplink::Send(source, "SVSKILL", user->nick, reason); +} - /* TOPIC */ - void SendTopic(const MessageSource &source, Channel *c) anope_override - { - UplinkSocket::Message(source) << "TOPIC " << c->name << " " << c->topic_setter << " " << c->topic_ts << " :" << c->topic; - } +void bahamut::senders::Login::Send(User *u, NickServ::Nick *na) +{ + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon); +} - /* UNSQLINE */ - void SendSQLineDel(const XLine *x) anope_override - { - UplinkSocket::Message() << "UNSQLINE " << x->mask; - } +void bahamut::senders::Logout::Send(User *u) +{ + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 1"); +} - /* JOIN - SJOIN */ - void SendJoin(User *user, Channel *c, const ChannelStatus *status) anope_override - { - UplinkSocket::Message(user) << "SJOIN " << c->creation_time << " " << c->name; - if (status) - { - /* First save the channel status incase uc->Status == status */ - ChannelStatus cs = *status; - /* If the user is internally on the channel with flags, kill them so that - * the stacker will allow this. - */ - ChanUserContainer *uc = c->FindUser(user); - if (uc != NULL) - uc->status.Clear(); - - BotInfo *setter = BotInfo::Find(user->GetUID()); - for (size_t i = 0; i < cs.Modes().length(); ++i) - c->SetMode(setter, ModeManager::FindChannelModeByChar(cs.Modes()[i]), user->GetUID(), false); - - if (uc != NULL) - uc->status = cs; - } - } +void bahamut::senders::ModeChannel::Send(const MessageSource &source, Channel *channel, const Anope::string &modes) +{ + IRCMessage message(source, "MODE", channel->name, channel->creation_time); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); +} - void SendAkill(User *u, XLine *x) anope_override - { - if (x->IsRegex() || x->HasNickOrReal()) - { - if (!u) - { - /* 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->manager->Check(it->second, x)) - this->SendAkill(it->second, x); - return; - } +void bahamut::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes) +{ + IRCMessage message(source, "SVSMODE", user->nick, user->timestamp); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); +} - const XLine *old = x; +void bahamut::senders::NickIntroduction::Send(User *user) +{ + Anope::string modes = "+" + user->GetModes(); + Uplink::Send("NICK", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, user->server->GetName(), 0, 0, user->realname); +} - if (old->manager->HasEntry("*@" + u->host)) - return; +void bahamut::senders::NOOP::Send(Server* server, bool set) +{ + Uplink::Send("SVSNOOP", server->GetSID(), set ? "+" : "-"); +} - /* We can't akill x as it has a nick and/or realname included, so create a new akill for *@host */ - x = new XLine("*@" + u->host, old->by, old->expires, old->reason, old->id); - old->manager->AddXLine(x); +void bahamut::senders::SGLine::Send(User*, XLine* x) +{ + Uplink::Send("SGLINE", x->GetMask().length(), x->GetMask() + ":" + x->GetReason()); +} - Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->mask << " because " << u->GetMask() << "#" << u->realname << " matches " << old->mask; - } +void bahamut::senders::SGLineDel::Send(XLine* x) +{ + Uplink::Send("UNSGLINE", 0, x->GetMask()); +} - /* ZLine if we can instead */ - if (x->GetUser() == "*") - { - cidr a(x->GetHost()); - if (a.valid()) - { - IRCD->SendSZLine(u, x); - return; - } - } +void bahamut::senders::SQLine::Send(User*, XLine* x) +{ + Uplink::Send(Me, "SQLINE", x->GetMask(), x->GetReason()); +} - // Calculate the time left before this would expire, capping it at 2 days - time_t timeleft = x->expires - Anope::CurTime; - if (timeleft > 172800) - timeleft = 172800; - UplinkSocket::Message() << "AKILL " << x->GetHost() << " " << x->GetUser() << " " << timeleft << " " << x->by << " " << Anope::CurTime << " :" << x->GetReason(); - } +void bahamut::senders::SQLineDel::Send(XLine* x) +{ + Uplink::Send("UNSQLINE", x->GetMask()); +} - /* - Note: if the stamp is null 0, the below usage is correct of Bahamut - */ - void SendSVSKillInternal(const MessageSource &source, User *user, const Anope::string &buf) anope_override - { - UplinkSocket::Message(source) << "SVSKILL " << user->nick << " :" << buf; - } +void bahamut::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; + if (timeleft > 172800 || !x->GetExpires()) + timeleft = 172800; + /* this will likely fail so its only here for legacy */ + Uplink::Send("SZLINE", x->GetHost(), x->GetReason()); + /* this is how we are supposed to deal with it */ + Uplink::Send("AKILL", x->GetHost(), "*", timeleft, x->GetBy(), Anope::CurTime, x->GetReason()); +} + +void bahamut::senders::SZLineDel::Send(XLine* x) +{ + /* this will likely fail so its only here for legacy */ + Uplink::Send("UNSZLINE", 0, x->GetHost()); + /* this is how we are supposed to deal with it */ + Uplink::Send("RAKILL", x->GetHost(), "*"); +} - void SendBOB() anope_override - { - UplinkSocket::Message() << "BURST"; - } +void bahamut::senders::SVSHold::Send(const Anope::string& nick, time_t t) +{ + Uplink::Send(Me, "SVSHOLD", nick, t, "Being held for registered user"); +} - void SendEOB() anope_override - { - UplinkSocket::Message() << "BURST 0"; - } +void bahamut::senders::SVSHoldDel::Send(const Anope::string& nick) +{ + Uplink::Send(Me, "SVSHOLD", nick, 0); +} - void SendClientIntroduction(User *u) anope_override - { - Anope::string modes = "+" + u->GetModes(); - UplinkSocket::Message() << "NICK " << u->nick << " 1 " << u->timestamp << " " << modes << " " << u->GetIdent() << " " << u->host << " " << u->server->GetName() << " 0 0 :" << u->realname; - } +void bahamut::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts) +{ + Uplink::Send("SVSNICK", u->GetUID(), newnick, ts); +} - /* SERVER */ - void SendServer(const Server *server) anope_override - { - UplinkSocket::Message() << "SERVER " << server->GetName() << " " << server->GetHops() << " :" << server->GetDescription(); - } +void bahamut::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) +{ + Uplink::Send(source, "TOPIC", channel->name, topic_setter, topic_ts, topic); +} - void SendConnect() anope_override - { - UplinkSocket::Message() << "PASS " << Config->Uplinks[Anope::CurrentUplink].password << " :TS"; - UplinkSocket::Message() << "CAPAB SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3"; - SendServer(Me); - /* - * SVINFO - * parv[0] = sender prefix - * parv[1] = TS_CURRENT for the server - * parv[2] = TS_MIN for the server - * parv[3] = server is standalone or connected to non-TS only - * parv[4] = server's idea of UTC time - */ - UplinkSocket::Message() << "SVINFO 3 1 0 :" << Anope::CurTime; - this->SendBOB(); - } +void bahamut::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg) +{ + Uplink::Send(source, "GLOBOPS", msg); +} - void SendChannel(Channel *c) anope_override - { - Anope::string modes = c->GetModes(true, true); - if (modes.empty()) - modes = "+"; - UplinkSocket::Message() << "SJOIN " << c->creation_time << " " << c->name << " " << modes << " :"; - } +#warning "not used" +class ChannelModeFlood : public ChannelModeParam +{ + public: + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } - void SendLogin(User *u, NickAlias *) anope_override + bool IsValid(Anope::string &value) const override { - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d %d", u->signon); - } + try + { + Anope::string rest; + if (!value.empty() && value[0] != ':' && convertTo<int>(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo<int>(rest.substr(1), rest, false) > 0 && rest.empty()) + return true; + } + catch (const ConvertException &) { } - void SendLogout(User *u) anope_override - { - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 1"); + return false; } }; -struct IRCDMessageBurst : IRCDMessage +bahamut::Proto::Proto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x") { - IRCDMessageBurst(Module *creator) : IRCDMessage(creator, "BURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + DefaultPseudoclientModes = "+"; + CanSVSNick = true; + CanSNLine = true; + CanSQLine = true; + CanSQLineChannel = true; + CanSZLine = true; + CanSVSHold = true; + MaxModes = 60; +} + +void bahamut::Proto::SendBOB() +{ + Uplink::Send("BURST"); +} - void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - /* If we found a server with the given source, that one just - * finished bursting. If there was no source, then our uplink - * server finished bursting. -GD - */ - Server *s = source.GetServer(); - if (!s) - s = Me->GetLinks().front(); - if (s) - s->Sync(true); - } -}; +void bahamut::Proto::SendEOB() +{ + Uplink::Send("BURST", 0); +} -struct IRCDMessageMode : IRCDMessage +void bahamut::Proto::Handshake() { - IRCDMessageMode(Module *creator, const Anope::string &sname) : IRCDMessage(creator, sname, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS"); + Uplink::Send("CAPAB", "SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3"); + IRCD->Send<messages::MessageServer>(Me); + /* + * SVINFO + * parv[0] = sender prefix + * parv[1] = TS_CURRENT for the server + * parv[2] = TS_MIN for the server + * parv[3] = server is standalone or connected to non-TS only + * parv[4] = server's idea of UTC time + */ + Uplink::Send("SVINFO", 3, 1, 0, Anope::CurTime); + this->SendBOB(); +} + +void bahamut::Burst::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +{ + Server *s = source.GetServer(); + s->Sync(true); +} - void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override +void bahamut::Mode::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) +{ + if (params.size() > 2 && IRCD->IsChannelValid(params[0])) { - if (params.size() > 2 && IRCD->IsChannelValid(params[0])) - { - Channel *c = Channel::Find(params[0]); - time_t ts = 0; - - try - { - ts = convertTo<time_t>(params[1]); - } - catch (const ConvertException &) { } - - Anope::string modes = params[2]; - for (unsigned int i = 3; i < params.size(); ++i) - modes += " " + params[i]; + Channel *c = Channel::Find(params[0]); + time_t ts = 0; - if (c) - c->SetModesInternal(source, modes, ts); - } - else + try { - User *u = User::Find(params[0]); - if (u) - u->SetModesInternal(source, "%s", params[1].c_str()); + ts = convertTo<time_t>(params[1]); } + catch (const ConvertException &) { } + + Anope::string modes = params[2]; + for (unsigned int i = 3; i < params.size(); ++i) + modes += " " + params[i]; + + if (c) + c->SetModesInternal(source, modes, ts); } -}; + else + { + User *u = User::Find(params[0]); + if (u) + u->SetModesInternal(source, "%s", params[1].c_str()); + } +} /* ** NICK - new @@ -362,207 +348,280 @@ struct IRCDMessageMode : IRCDMessage ** parv[0] = new nickname ** parv[1] = hopcount */ -struct IRCDMessageNick : IRCDMessage +void bahamut::Nick::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - IRCDMessageNick(Module *creator) : IRCDMessage(creator, "NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } - - void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + if (params.size() == 10) { - if (params.size() == 10) + Server *s = Server::Find(params[6]); + if (s == nullptr) { - Server *s = Server::Find(params[6]); - if (s == NULL) - { - Log(LOG_DEBUG) << "User " << params[0] << " introduced from non-existent server " << params[6] << "?"; - return; - } + Anope::Logger.Debug("User {0} introduced from non-existent server {1}", params[0], params[6]); + return; + } - NickAlias *na = NULL; - time_t signon = params[2].is_pos_number_only() ? convertTo<time_t>(params[2]) : 0, - stamp = params[7].is_pos_number_only() ? convertTo<time_t>(params[7]) : 0; - if (signon && signon == stamp) - na = NickAlias::Find(params[0]); + NickServ::Nick *na = nullptr; + time_t signon = 0, stamp = 0; - User::OnIntroduce(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? *na->nc : NULL); + try + { + signon = convertTo<time_t>(params[2]); + stamp = convertTo<time_t>(params[7]); } - else + catch (const ConvertException &) { - User *u = source.GetUser(); - - if (u) - u->ChangeNick(params[0]); } + + if (signon && signon == stamp && NickServ::service) + na = NickServ::service->FindNick(params[0]); + + User::OnIntroduce(params[0], params[4], params[5], "", params[8], s, params[9], signon, params[3], "", na ? na->GetAccount() : nullptr); } -}; + else + { + User *u = source.GetUser(); -struct IRCDMessageServer : IRCDMessage + if (u) + u->ChangeNick(params[0]); + } +} + +void bahamut::ServerMessage::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - IRCDMessageServer(Module *creator) : IRCDMessage(creator, "SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + unsigned int hops = 0; - void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + try { - unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo<unsigned>(params[1]) : 0; - new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[2]); + hops = convertTo<unsigned>(params[1]); } -}; + catch (const ConvertException &) { } -struct IRCDMessageSJoin : IRCDMessage + new Server(source.GetServer(), params[0], hops, params[2]); +} + +void bahamut::SJoin::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - IRCDMessageSJoin(Module *creator) : IRCDMessage(creator, "SJOIN", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + Anope::string modes; + if (params.size() >= 4) + for (unsigned i = 2; i < params.size(); ++i) + modes += " " + params[i]; + if (!modes.empty()) + modes.erase(modes.begin()); - void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override - { - Anope::string modes; - if (params.size() >= 4) - for (unsigned i = 2; i < params.size(); ++i) - modes += " " + params[i]; - if (!modes.empty()) - modes.erase(modes.begin()); + std::list<rfc1459::Join::SJoinUser> users; - std::list<Message::Join::SJoinUser> users; + /* For some reason, bahamut will send a SJOIN from the user joining a channel + * if the channel already existed + */ + if (source.GetUser()) + { + rfc1459::Join::SJoinUser sju; + sju.second = source.GetUser(); + users.push_back(sju); + } + else + { + spacesepstream sep(params[params.size() - 1]); + Anope::string buf; - /* For some reason, bahamut will send a SJOIN from the user joining a channel - * if the channel already existed - */ - if (source.GetUser()) + while (sep.GetToken(buf)) { - Message::Join::SJoinUser sju; - sju.second = source.GetUser(); - users.push_back(sju); - } - else - { - spacesepstream sep(params[params.size() - 1]); - Anope::string buf; + rfc1459::Join::SJoinUser sju; + + /* Get prefixes from the nick */ + for (char ch; !buf.empty() && (ch = ModeManager::GetStatusChar(buf[0]));) + { + buf.erase(buf.begin()); + sju.first.AddMode(ch); + } - while (sep.GetToken(buf)) + sju.second = User::Find(buf); + if (!sju.second) { - Message::Join::SJoinUser sju; - - /* Get prefixes from the nick */ - for (char ch; (ch = ModeManager::GetStatusChar(buf[0]));) - { - buf.erase(buf.begin()); - sju.first.AddMode(ch); - } - - sju.second = User::Find(buf); - if (!sju.second) - { - Log(LOG_DEBUG) << "SJOIN for non-existent user " << buf << " on " << params[1]; - continue; - } - - users.push_back(sju); + Anope::Logger.Log("SJOIN for non-existent user {0} on {1}", buf, params[1]); + continue; } + + users.push_back(sju); } + } - time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo<time_t>(params[0]) : Anope::CurTime; - Message::Join::SJoin(source, params[1], ts, modes, users); + time_t ts = Anope::CurTime; + + try + { + ts = convertTo<time_t>(params[0]); } -}; + catch (const ConvertException &) { } -struct IRCDMessageTopic : IRCDMessage + rfc1459::Join::SJoin(source, params[1], ts, modes, users); +} + +void bahamut::Topic::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - IRCDMessageTopic(Module *creator) : IRCDMessage(creator, "TOPIC", 4) { } + Channel *c = Channel::Find(params[0]); + time_t ts = Anope::CurTime; - void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) anope_override + try { - Channel *c = Channel::Find(params[0]); - if (c) - c->ChangeTopicInternal(source.GetUser(), params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo<time_t>(params[2]) : Anope::CurTime); + ts = convertTo<time_t>(params[2]); } -}; + catch (const ConvertException &) { } + + if (c) + c->ChangeTopicInternal(source.GetUser(), params[1], params[3], ts); +} class ProtoBahamut : public Module + , public EventHook<Event::UserNickChange> { - BahamutIRCdProto ircd_proto; + bahamut::Proto ircd_proto; /* Core message handlers */ - Message::Away message_away; - Message::Capab message_capab; - Message::Error message_error; - Message::Invite message_invite; - Message::Join message_join; - Message::Kick message_kick; - Message::Kill message_kill; - Message::MOTD message_motd; - Message::Notice message_notice; - Message::Part message_part; - Message::Ping message_ping; - Message::Privmsg message_privmsg; - Message::Quit message_quit; - Message::SQuit message_squit; - Message::Stats message_stats; - Message::Time message_time; - Message::Version message_version; - Message::Whois message_whois; + rfc1459::Away message_away; + rfc1459::Capab message_capab; + rfc1459::Error message_error; + rfc1459::Invite message_invite; + rfc1459::Join message_join; + rfc1459::Kick message_kick; + rfc1459::Kill message_kill; + rfc1459::MOTD message_motd; + rfc1459::Notice message_notice; + rfc1459::Part message_part; + rfc1459::Ping message_ping; + rfc1459::Privmsg message_privmsg; + rfc1459::Quit message_quit; + rfc1459::SQuit message_squit; + rfc1459::Stats message_stats; + rfc1459::Time message_time; + rfc1459::Version message_version; + rfc1459::Whois message_whois; /* Our message handlers */ - IRCDMessageBurst message_burst; - IRCDMessageMode message_mode, message_svsmode; - IRCDMessageNick message_nick; - IRCDMessageServer message_server; - IRCDMessageSJoin message_sjoin; - IRCDMessageTopic message_topic; - - void AddModes() - { - /* Add user modes */ - ModeManager::AddUserMode(new UserModeOperOnly("SERV_ADMIN", 'A')); - ModeManager::AddUserMode(new UserMode("REGPRIV", 'R')); - ModeManager::AddUserMode(new UserModeOperOnly("ADMIN", 'a')); - ModeManager::AddUserMode(new UserMode("INVIS", 'i')); - ModeManager::AddUserMode(new UserModeOperOnly("OPER", 'o')); - ModeManager::AddUserMode(new UserModeNoone("REGISTERED", 'r')); - ModeManager::AddUserMode(new UserModeOperOnly("SNOMASK", 's')); - ModeManager::AddUserMode(new UserModeOperOnly("WALLOPS", 'w')); - ModeManager::AddUserMode(new UserMode("DEAF", 'd')); - - /* b/e/I */ - ModeManager::AddChannelMode(new ChannelModeList("BAN", 'b')); - - /* v/h/o/a/q */ - ModeManager::AddChannelMode(new ChannelModeStatus("VOICE", 'v', '+', 0)); - ModeManager::AddChannelMode(new ChannelModeStatus("OP", 'o', '@', 1)); - - /* Add channel modes */ - ModeManager::AddChannelMode(new ChannelMode("BLOCKCOLOR", 'c')); - ModeManager::AddChannelMode(new ChannelMode("INVITE", 'i')); - ModeManager::AddChannelMode(new ChannelModeFlood('f', false)); - ModeManager::AddChannelMode(new ChannelModeKey('k')); - ModeManager::AddChannelMode(new ChannelModeParam("LIMIT", 'l', true)); - ModeManager::AddChannelMode(new ChannelMode("MODERATED", 'm')); - ModeManager::AddChannelMode(new ChannelMode("NOEXTERNAL", 'n')); - ModeManager::AddChannelMode(new ChannelMode("PRIVATE", 'p')); - ModeManager::AddChannelMode(new ChannelModeNoone("REGISTERED", 'r')); - ModeManager::AddChannelMode(new ChannelMode("SECRET", 's')); - ModeManager::AddChannelMode(new ChannelMode("TOPIC", 't')); - ModeManager::AddChannelMode(new ChannelMode("REGMODERATED", 'M')); - ModeManager::AddChannelMode(new ChannelModeOperOnly("OPERONLY", 'O')); - ModeManager::AddChannelMode(new ChannelMode("REGISTEREDONLY", 'R')); - } + bahamut::Burst message_burst; + bahamut::Mode message_mode, message_svsmode; + bahamut::Nick message_nick; + bahamut::ServerMessage message_server; + bahamut::SJoin message_sjoin; + bahamut::Topic message_topic; + + /* Core message senders */ + rfc1459::senders::GlobalNotice sender_global_notice; + rfc1459::senders::GlobalPrivmsg sender_global_privmsg; + rfc1459::senders::Invite sender_invite; + rfc1459::senders::Kick sender_kick; + 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::MessageServer sender_server; + rfc1459::senders::SQuit sender_squit; + + /* Our message senders */ + bahamut::senders::Akill sender_akill; + bahamut::senders::AkillDel sender_akill_del; + bahamut::senders::MessageChannel sender_channel; + bahamut::senders::Join sender_join; + bahamut::senders::Kill sender_kill; + bahamut::senders::Login sender_login; + bahamut::senders::Logout sender_logout; + bahamut::senders::ModeChannel sender_mode_channel; + bahamut::senders::ModeUser sender_mode_user; + bahamut::senders::NickIntroduction sender_nickintroduction; + bahamut::senders::NOOP sender_noop; + bahamut::senders::SGLine sender_sgline; + bahamut::senders::SGLineDel sender_sgline_del; + bahamut::senders::SQLine sender_sqline; + bahamut::senders::SQLineDel sender_sqline_del; + bahamut::senders::SZLine sender_szline; + bahamut::senders::SZLineDel sender_szline_del; + bahamut::senders::SVSHold sender_svshold; + bahamut::senders::SVSHoldDel sender_svsholddel; + bahamut::senders::SVSNick sender_svsnick; + bahamut::senders::Topic sender_topic; + bahamut::senders::Wallops sender_wallops; public: - ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR), - ircd_proto(this), - message_away(this), message_capab(this), message_error(this), message_invite(this), - message_join(this), message_kick(this), message_kill(this), message_motd(this), message_notice(this), - message_part(this), message_ping(this), message_privmsg(this), message_quit(this), - message_squit(this), message_stats(this), message_time(this), message_version(this), message_whois(this), - - message_burst(this), message_mode(this, "MODE"), message_svsmode(this, "SVSMODE"), - message_nick(this), message_server(this), message_sjoin(this), message_topic(this) - { - - this->AddModes(); - - } - - void OnUserNickChange(User *u, const Anope::string &) anope_override + ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) + , EventHook<Event::UserNickChange>(this) + , ircd_proto(this) + , message_away(this) + , message_capab(this) + , message_error(this) + , message_invite(this) + , message_join(this) + , message_kick(this) + , message_kill(this) + , message_motd(this) + , message_notice(this) + , message_part(this) + , message_ping(this) + , message_privmsg(this) + , message_quit(this) + , message_squit(this) + , message_stats(this) + , message_time(this) + , message_version(this) + , message_whois(this) + + , message_burst(this) + , message_mode(this, "MODE") + , message_svsmode(this, "SVSMODE") + , message_nick(this) + , message_server(this) + , message_sjoin(this) + , message_topic(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_kill(this) + , sender_login(this) + , sender_logout(this) + , sender_mode_channel(this) + , sender_mode_user(this) + , sender_nickchange(this) + , sender_nickintroduction(this) + , sender_noop(this) + , sender_topic(this) + , sender_notice(this) + , sender_part(this) + , sender_ping(this) + , sender_pong(this) + , sender_privmsg(this) + , sender_quit(this) + , sender_server(this) + , sender_sgline(this) + , sender_sgline_del(this) + , sender_sqline(this) + , sender_sqline_del(this) + , sender_szline(this) + , sender_szline_del(this) + , sender_squit(this) + , sender_svshold(this) + , sender_svsholddel(this) + , sender_svsnick(this) + , sender_wallops(this) + { + IRCD = &ircd_proto; + } + + ~ProtoBahamut() + { + IRCD = nullptr; + } + + void OnUserNickChange(User *u, const Anope::string &) override { u->RemoveModeInternal(Me, ModeManager::FindUserModeByName("REGISTERED")); - IRCD->SendLogout(u); + sender_logout.Send(u); } }; |