diff options
| author | Adam <Adam@anope.org> | 2016-12-17 21:44:22 -0500 |
|---|---|---|
| committer | Adam <Adam@anope.org> | 2016-12-17 21:44:22 -0500 |
| commit | 4fcbbbe4fbc137841b47c8e2372477b85649270a (patch) | |
| tree | f2a5fd3b5a77ef0384df6e2712fdd74f832d7dfe /modules | |
| parent | ed08d1a31119adb379f8bec46d7ad47ee35c4c92 (diff) | |
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
Diffstat (limited to 'modules')
30 files changed, 1872 insertions, 1197 deletions
diff --git a/modules/botserv/bot.cpp b/modules/botserv/bot.cpp index 30550df56..082bd6337 100644 --- a/modules/botserv/bot.cpp +++ b/modules/botserv/bot.cpp @@ -232,7 +232,10 @@ class CommandBSBot : public Command bi->introduced = false; } else - IRCD->SendNickChange(bi, nick); + { + IRCD->Send<messages::NickChange>(bi, nick, Anope::CurTime); + bi->timestamp = Anope::CurTime; + } if (!nick.equals_cs(bi->nick)) { diff --git a/modules/botserv/main/botserv.cpp b/modules/botserv/main/botserv.cpp index 4f3d4c92b..4b0309b31 100644 --- a/modules/botserv/main/botserv.cpp +++ b/modules/botserv/main/botserv.cpp @@ -62,6 +62,7 @@ class BotServCore : public Module, public BotServ::BotServService void OnBotAssign(User *sender, ChanServ::Channel *ci, ServiceBot *bi) override { + printf("on bot assign !\n"); if (ci->c && ci->c->users.size() >= Config->GetModule(this)->Get<unsigned>("minusers")) { ChannelStatus status(Config->GetModule(this)->Get<Anope::string>("botmodes")); diff --git a/modules/chanserv/invite.cpp b/modules/chanserv/invite.cpp index b6d0f19c9..9c21bc704 100644 --- a/modules/chanserv/invite.cpp +++ b/modules/chanserv/invite.cpp @@ -78,7 +78,7 @@ class CommandCSInvite : public Command bool override = !source.AccessFor(ci).HasPriv("INVITE"); - IRCD->SendInvite(ci->WhoSends(), c, u2); + IRCD->Send<messages::Invite>(ci->WhoSends(), c, u2); if (u2 != u) { source.Reply(_("\002{0}\002 has been invited to \002{1}\002."), u2->nick, c->name); diff --git a/modules/chanserv/main/chanserv.cpp b/modules/chanserv/main/chanserv.cpp index b6aedb0dd..492f64459 100644 --- a/modules/chanserv/main/chanserv.cpp +++ b/modules/chanserv/main/chanserv.cpp @@ -471,7 +471,7 @@ class ChanServCore : public Module if (ModeManager::FindChannelModeByName("PERM") != NULL) { if (c) - IRCD->SendChannel(ci->c); + IRCD->Send<messages::MessageChannel>(ci->c); ci->c->SetMode(NULL, "PERM"); } else @@ -513,7 +513,7 @@ class ChanServCore : public Module { ::Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->GetTimeRegistered(); c->creation_time = c->ci->GetTimeRegistered(); - IRCD->SendChannel(c); + IRCD->Send<messages::MessageChannel>(c); c->Reset(); } } diff --git a/modules/chanserv/set.cpp b/modules/chanserv/set.cpp index 89eb4985a..833817cde 100644 --- a/modules/chanserv/set.cpp +++ b/modules/chanserv/set.cpp @@ -1242,7 +1242,7 @@ class CSSet : public Module { Log(LOG_DEBUG) << "Changing TS of " << c->name << " from " << c->creation_time << " to " << c->ci->GetTimeRegistered(); c->creation_time = c->ci->GetTimeRegistered(); - IRCD->SendChannel(c); + IRCD->Send<messages::MessageChannel>(c); c->Reset(); } } diff --git a/modules/dnsbl.cpp b/modules/dnsbl.cpp index a2c8a4380..f8d35bf71 100644 --- a/modules/dnsbl.cpp +++ b/modules/dnsbl.cpp @@ -107,7 +107,7 @@ class DNSBLResolver : public Request } else { - IRCD->SendAkill(NULL, x); + IRCD->Send<messages::Akill>(nullptr, x); delete x; } } diff --git a/modules/hostserv/main/hostserv.cpp b/modules/hostserv/main/hostserv.cpp index 4ff348f2b..f7ba03418 100644 --- a/modules/hostserv/main/hostserv.cpp +++ b/modules/hostserv/main/hostserv.cpp @@ -76,7 +76,7 @@ class HostServCore : public Module if (u->vhost.empty() || !u->vhost.equals_cs(vhost->GetHost()) || (!vhost->GetIdent().empty() && !u->GetVIdent().equals_cs(vhost->GetIdent()))) { - IRCD->SendVhost(u, vhost->GetIdent(), vhost->GetHost()); + IRCD->Send<messages::VhostSet>(u, vhost->GetIdent(), vhost->GetHost()); u->vhost = vhost->GetHost(); u->UpdateHost(); @@ -124,7 +124,7 @@ class HostServCore : public Module if (vhost == nullptr) return; - IRCD->SendVhost(u, vhost->GetIdent(), vhost->GetHost()); + IRCD->Send<messages::VhostSet>(u, vhost->GetIdent(), vhost->GetHost()); u->vhost = vhost->GetHost(); u->UpdateHost(); @@ -150,7 +150,7 @@ class HostServCore : public Module User *u = User::Find(na->GetNick()); if (u && u->Account() == na->GetAccount()) - IRCD->SendVhostDel(u); + IRCD->Send<messages::VhostDel>(u); } } diff --git a/modules/hostserv/off.cpp b/modules/hostserv/off.cpp index 1d7d91876..e1af7def4 100644 --- a/modules/hostserv/off.cpp +++ b/modules/hostserv/off.cpp @@ -42,7 +42,7 @@ class CommandHSOff : public Command // XXX vident? u->vhost.clear(); - IRCD->SendVhostDel(u); + IRCD->Send<messages::VhostDel>(u); Log(LOG_COMMAND, source, this) << "to disable their vhost"; source.Reply(_("Your vhost was removed and the normal cloaking restored.")); } diff --git a/modules/hostserv/on.cpp b/modules/hostserv/on.cpp index c8f4211de..3041f65a5 100644 --- a/modules/hostserv/on.cpp +++ b/modules/hostserv/on.cpp @@ -60,7 +60,7 @@ class CommandHSOn : public Command source.Reply(_("Your vhost of \002{0}\002 is now activated."), vhost->Mask()); Log(LOG_COMMAND, source, this) << "to enable their vhost of " << vhost->Mask(); - IRCD->SendVhost(u, vhost->GetIdent(), vhost->GetHost()); + IRCD->Send<messages::VhostSet>(u, vhost->GetIdent(), vhost->GetHost()); u->vhost = vhost->GetHost(); if (IRCD->CanSetVIdent && !vhost->GetIdent().empty()) u->SetVIdent(vhost->GetIdent()); diff --git a/modules/nickserv/ajoin.cpp b/modules/nickserv/ajoin.cpp index 5973c95ac..0d708143c 100644 --- a/modules/nickserv/ajoin.cpp +++ b/modules/nickserv/ajoin.cpp @@ -371,7 +371,7 @@ class NSAJoin : public Module { try { - unsigned limit = convertTo<unsigned>(l); + unsigned int limit = convertTo<unsigned int>(l); if (c->users.size() >= limit) need_invite = true; } @@ -384,10 +384,10 @@ class NSAJoin : public Module { if (!u_access.HasPriv("INVITE")) continue; - IRCD->SendInvite(NickServ, c, u); + IRCD->Send<messages::Invite>(NickServ, c, u); } - IRCD->SendSVSJoin(NickServ, u, entry->GetChannel(), key); + IRCD->Send<messages::SVSJoin>(NickServ, u, entry->GetChannel(), key); } } }; diff --git a/modules/nickserv/logout.cpp b/modules/nickserv/logout.cpp index 6a9d119ad..0e6cdb46a 100644 --- a/modules/nickserv/logout.cpp +++ b/modules/nickserv/logout.cpp @@ -68,7 +68,7 @@ class CommandNSLogout : public Command else source.Reply(_("You have been logged out.")); - IRCD->SendLogout(u2); + IRCD->Send<messages::Logout>(u2); u2->RemoveMode(source.service, "REGISTERED"); u2->Logout(); diff --git a/modules/nickserv/main/nickserv.cpp b/modules/nickserv/main/nickserv.cpp index 60b136db1..3741d119b 100644 --- a/modules/nickserv/main/nickserv.cpp +++ b/modules/nickserv/main/nickserv.cpp @@ -115,7 +115,7 @@ class NickServRelease : public User, public Timer NickServReleases.insert(std::make_pair(this->nick, this)); - IRCD->SendClientIntroduction(this); + IRCD->Send<messages::NickIntroduction>(this); } ~NickServRelease() @@ -168,7 +168,7 @@ class NickServCore : public Module, public NickServ::NickServService new NickServHeld(this, na, Config->GetModule("nickserv/main")->Get<time_t>("releasetimeout", "1m")); if (IRCD->CanSVSHold) - IRCD->SendSVSHold(na->GetNick(), Config->GetModule("nickserv/main")->Get<time_t>("releasetimeout", "1m")); + IRCD->Send<messages::SVSHold>(na->GetNick(), Config->GetModule("nickserv/main")->Get<time_t>("releasetimeout", "1m")); else new NickServRelease(this, na, Config->GetModule("nickserv/main")->Get<time_t>("releasetimeout", "1m")); } @@ -324,7 +324,7 @@ class NickServCore : public Module, public NickServ::NickServService else { u->SendMessage(*NickServ, _("Your nickname is now being changed to \002%s\002"), guestnick.c_str()); - IRCD->SendForceNickChange(u, guestnick, Anope::CurTime); + IRCD->Send<messages::SVSNick>(u, guestnick, Anope::CurTime); } } else @@ -338,7 +338,7 @@ class NickServCore : public Module, public NickServ::NickServService if (held.HasExt(na)) { if (IRCD->CanSVSHold) - IRCD->SendSVSHoldDel(na->GetNick()); + IRCD->Send<messages::SVSHoldDel>(na->GetNick()); else { User *u = User::Find(na->GetNick(), true); @@ -418,7 +418,7 @@ class NickServCore : public Module, public NickServ::NickServService User *u = User::Find(na->GetNick(), true); if (u && u->Account() == na->GetAccount()) { - IRCD->SendLogout(u); + IRCD->Send<messages::Logout>(u); u->RemoveMode(NickServ, "REGISTERED"); u->Logout(); } @@ -432,7 +432,7 @@ class NickServCore : public Module, public NickServ::NickServService for (unsigned int i = nc->users.size(); i > 0; --i) { User *user = nc->users[i - 1]; - IRCD->SendLogout(user); + IRCD->Send<messages::Logout>(user); user->RemoveMode(NickServ, "REGISTERED"); user->Logout(); EventManager::Get()->Dispatch(&Event::NickLogout::OnNickLogout, user); @@ -552,7 +552,7 @@ class NickServCore : public Module, public NickServ::NickServService else { /* Reset +r and re-send account (even though it really should be set at this point) */ - IRCD->SendLogin(u, na); + IRCD->Send<messages::Login>(u, na); if (!Config->GetModule("nickserv/main")->Get<bool>("nonicknameownership") && na->GetAccount() == u->Account() && !na->GetAccount()->IsUnconfirmed()) u->SetMode(NickServ, "REGISTERED"); Log(u, "", NickServ) << u->GetMask() << " automatically identified for group " << u->Account()->GetDisplay(); diff --git a/modules/nickserv/recover.cpp b/modules/nickserv/recover.cpp index f3fa24bb6..60a0bee2f 100644 --- a/modules/nickserv/recover.cpp +++ b/modules/nickserv/recover.cpp @@ -92,7 +92,7 @@ class NSRecoverRequestListener : public NickServ::IdentifyRequestListener source.Reply(_("Ghost with your nick has been killed.")); if (IRCD->CanSVSNick) - IRCD->SendForceNickChange(source.GetUser(), user, Anope::CurTime); + IRCD->Send<messages::SVSNick>(source.GetUser(), user, Anope::CurTime); } /* User is not identified or not identified to the same account as the person using this command */ else @@ -266,7 +266,7 @@ class NSRecover : public Module if (u->FindChannel(c)) this->OnJoinChannel(u, c); else if (IRCD->CanSVSJoin) - IRCD->SendSVSJoin(NickServ, u, cname, ""); + IRCD->Send<messages::SVSJoin>(NickServ, u, cname, ""); } } @@ -276,7 +276,7 @@ class NSRecover : public Module if (svs->from) { // svsnick from to to - IRCD->SendForceNickChange(svs->from, svs->to, Anope::CurTime); + IRCD->Send<messages::SVSNick>(svs->from, svs->to, Anope::CurTime); } svsnick.Unset(u); diff --git a/modules/nickserv/register.cpp b/modules/nickserv/register.cpp index 4ceb3f113..b06e08075 100644 --- a/modules/nickserv/register.cpp +++ b/modules/nickserv/register.cpp @@ -59,7 +59,7 @@ class CommandNSConfirm : public Command /* Login the users online already */ for (User *u : na->GetAccount()->users) { - IRCD->SendLogin(u, na); + IRCD->Send<messages::Login>(u, na); NickServ::Nick *u_na = NickServ::FindNick(u->nick); @@ -90,7 +90,7 @@ class CommandNSConfirm : public Command NickServ::Nick *na = NickServ::FindNick(source.GetNick()); if (na) { - IRCD->SendLogin(source.GetUser(), na); + IRCD->Send<messages::Login>(source.GetUser(), na); if (!Config->GetModule("nickserv/main")->Get<bool>("nonicknameownership") && na->GetAccount() == source.GetAccount() && !na->GetAccount()->IsUnconfirmed()) source.GetUser()->SetMode(source.service, "REGISTERED"); } diff --git a/modules/nickserv/set.cpp b/modules/nickserv/set.cpp index 136d43be8..c7d03f8d2 100644 --- a/modules/nickserv/set.cpp +++ b/modules/nickserv/set.cpp @@ -362,7 +362,7 @@ class CommandNSSetDisplay : public Command for (User *u : user_na->GetAccount()->users) { - IRCD->SendLogin(u, user_na); + IRCD->Send<messages::Login>(u, user_na); } source.Reply(_("The new display is now \002{0}\002."), user_na->GetAccount()->GetDisplay()); diff --git a/modules/operserv/jupe.cpp b/modules/operserv/jupe.cpp index 2f9386eda..882effa4f 100644 --- a/modules/operserv/jupe.cpp +++ b/modules/operserv/jupe.cpp @@ -57,11 +57,11 @@ class CommandOSJupe : public Command Anope::string sid = IRCD->SID_Retrieve(); if (server) { - IRCD->SendSquit(server, rbuf); + IRCD->Send<messages::SQuit>(server, rbuf); server->Delete(rbuf); } Server *juped_server = new Server(Me, jserver, 1, rbuf, sid, true); - IRCD->SendServer(juped_server); + IRCD->Send<messages::MessageServer>(juped_server); Log(LOG_ADMIN, source, this) << "on " << jserver << " (" << rbuf << ")"; } diff --git a/modules/operserv/main/operserv.cpp b/modules/operserv/main/operserv.cpp index 09dc3bbac..fc8dbf423 100644 --- a/modules/operserv/main/operserv.cpp +++ b/modules/operserv/main/operserv.cpp @@ -38,12 +38,12 @@ class SGLineManager : public XLineManager void Send(User *u, XLine *x) override { - IRCD->SendAkill(u, x); + IRCD->Send<messages::Akill>(u, x); } void SendDel(XLine *x) override { - IRCD->SendAkillDel(x); + IRCD->Send<messages::AkillDel>(x); } bool Check(User *u, XLine *x) override @@ -106,7 +106,7 @@ class SQLineManager : public XLineManager } else if (x->GetMask()[0] != '#' || IRCD->CanSQLineChannel) { - IRCD->SendSQLine(u, x); + IRCD->Send<messages::SQLine>(u, x); /* If it is an oper, assume they're walking it, otherwise kill for good measure */ if (u && !u->HasMode("OPER")) u->Kill(Config->GetClient("OperServ"), "Q-Lined: " + x->GetReason()); @@ -118,7 +118,7 @@ class SQLineManager : public XLineManager if (!IRCD->CanSQLine || x->IsRegex()) ; else if (x->GetMask()[0] != '#' || IRCD->CanSQLineChannel) - IRCD->SendSQLineDel(x); + IRCD->Send<messages::SQLineDel>(x); } bool Check(User *u, XLine *x) override @@ -168,7 +168,7 @@ class SNLineManager : public XLineManager void Send(User *u, XLine *x) override { if (IRCD->CanSNLine && !x->IsRegex()) - IRCD->SendSGLine(u, x); + IRCD->Send<messages::SGLine>(u, x); if (u) u->Kill(Config->GetClient("OperServ"), "SNLined: " + x->GetReason()); @@ -177,7 +177,7 @@ class SNLineManager : public XLineManager void SendDel(XLine *x) override { if (IRCD->CanSNLine && !x->IsRegex()) - IRCD->SendSGLineDel(x); + IRCD->Send<messages::SGLineDel>(x); } bool Check(User *u, XLine *x) override diff --git a/modules/operserv/noop.cpp b/modules/operserv/noop.cpp index 2d813a0cc..329a6c338 100644 --- a/modules/operserv/noop.cpp +++ b/modules/operserv/noop.cpp @@ -50,7 +50,7 @@ class CommandOSNOOP : public Command if (cmd.equals_ci("SET")) { /* Remove the O:lines */ - IRCD->SendSVSNOOP(s, true); + IRCD->Send<messages::NOOP>(s, true); s->Extend<Anope::string>("noop", source.GetNick()); Log(LOG_ADMIN, source, this) << "SET on " << s->GetName(); @@ -69,7 +69,7 @@ class CommandOSNOOP : public Command else if (cmd.equals_ci("REVOKE")) { s->Shrink<Anope::string>("noop"); - IRCD->SendSVSNOOP(s, false); + IRCD->Send<messages::NOOP>(s, false); Log(LOG_ADMIN, source, this) << "REVOKE on " << s->GetName(); source.Reply(_("All O:lines of \002{0}\002 have been reset."), s->GetName()); } diff --git a/modules/operserv/svs.cpp b/modules/operserv/svs.cpp index 81138740f..ccba9d8d1 100644 --- a/modules/operserv/svs.cpp +++ b/modules/operserv/svs.cpp @@ -69,7 +69,7 @@ class CommandOSSVSNick : public Command source.Reply(_("\002{0}\002 is now being changed to \002{1}\002."), nick, newnick); Log(LOG_ADMIN, source, this) << "to change " << nick << " to " << newnick; - IRCD->SendForceNickChange(u2, newnick, Anope::CurTime); + IRCD->Send<messages::SVSNick>(u2, newnick, Anope::CurTime); } bool OnHelp(CommandSource &source, const Anope::string &subcommand) override @@ -122,7 +122,7 @@ class CommandOSSVSJoin : public Command return; } - IRCD->SendSVSJoin(*source.service, target, params[1], ""); + IRCD->Send<messages::SVSJoin>(*source.service, target, params[1], ""); Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to join " << params[1]; source.Reply(_("\002{0}\002 has been joined to \002{1}\002."), target->nick, params[1]); } @@ -178,7 +178,7 @@ class CommandOSSVSPart : public Command } const Anope::string &reason = params.size() > 2 ? params[2] : ""; - IRCD->SendSVSPart(*source.service, target, params[1], reason); + IRCD->Send<messages::SVSPart>(*source.service, target, params[1], reason); if (!reason.empty()) Log(LOG_ADMIN, source, this) << "to force " << target->nick << " to part " << c->name << " with reason " << reason; else diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 46ffb3ea2..cdb05e7f7 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -23,103 +23,175 @@ #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 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; + + 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); + + Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#" << u->realname << " matches " << old->GetMask(); } -}; -bahamut::Proto::Proto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x") -{ - DefaultPseudoclientModes = "+"; - CanSVSNick = true; - CanSNLine = true; - CanSQLine = true; - CanSQLineChannel = true; - CanSZLine = true; - CanSVSHold = true; - MaxModes = 60; + /* ZLine if we can instead */ + if (x->GetUser() == "*") + { + cidr a(x->GetHost()); + if (a.valid()) + { + IRCD->Send<messages::SZLine>(u, x); + return; + } + } + + // 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; + + Uplink::Send("AKILL", x->GetHost(), x->GetUser(), timeleft, x->GetBy(), Anope::CurTime, x->GetReason()); } -void bahamut::Proto::SendMode(const MessageSource &source, Channel *dest, const Anope::string &buf) +void bahamut::senders::AkillDel::Send(XLine* x) { - if (Servers::Capab.count("TSMODE") > 0) + if (x->IsRegex() || x->HasNickOrReal()) + return; + + /* ZLine if we can instead */ + if (x->GetUser() == "*") { - IRCMessage message(source, "MODE", dest->name, dest->creation_time); - message.TokenizeAndPush(buf); - Uplink::SendMessage(message); + cidr a(x->GetHost()); + if (a.valid()) + { + IRCD->Send<messages::SZLineDel>(x); + return; + } } - else + + Uplink::Send("RAKKILL", x->GetHost(), x->GetUser()); +} + +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, ""); +} + +void bahamut::senders::Join::Send(User* user, Channel* c, const ChannelStatus* status) +{ + Uplink::Send(user, "SJOIN", c->creation_time, c->name); + + if (status) { - IRCDProto::SendMode(source, dest, buf); + /* 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(); + + 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); + + if (uc != NULL) + uc->status = cs; } } -void bahamut::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf) +void bahamut::senders::Kill::Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) { - IRCMessage message(source, "SVSMODE", u->nick, u->timestamp); - message.TokenizeAndPush(buf); - Uplink::SendMessage(message); + Uplink::Send(source, "SVSKILL", target, reason); +} + +/* + 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); } -void bahamut::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) +void bahamut::senders::Login::Send(User *u, NickServ::Nick *na) { - Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg); + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon); } -void bahamut::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) +void bahamut::senders::Logout::Send(User *u) { - Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg); + IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 1"); } -/* SVSHOLD - set */ -void bahamut::Proto::SendSVSHold(const Anope::string &nick, time_t time) +void bahamut::senders::ModeChannel::Send(const MessageSource &source, Channel *channel, const Anope::string &modes) { - Uplink::Send(Me, "SVSHOLD", nick, time, "Being held for registered user"); + IRCMessage message(source, "MODE", channel->name, channel->creation_time); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); } -/* SVSHOLD - release */ -void bahamut::Proto::SendSVSHoldDel(const Anope::string &nick) +void bahamut::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes) { - Uplink::Send(Me, "SVSHOLD", nick, 0); + IRCMessage message(source, "SVSMODE", user->nick, user->timestamp); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); } -/* SQLINE */ -void bahamut::Proto::SendSQLine(User *, XLine *x) +void bahamut::senders::NickIntroduction::Send(User *user) { - Uplink::Send(Me, "SQLINE", x->GetMask(), x->GetReason()); + 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); +} + +void bahamut::senders::NOOP::Send(Server* server, bool set) +{ + Uplink::Send("SVSNOOP", server->GetSID(), set ? "+" : "-"); +} + +void bahamut::senders::SGLine::Send(User*, XLine* x) +{ + Uplink::Send("SGLINE", x->GetMask().length(), x->GetMask() + ":" + x->GetReason()); } -/* UNSLINE */ -void bahamut::Proto::SendSGLineDel(XLine *x) +void bahamut::senders::SGLineDel::Send(XLine* x) { Uplink::Send("UNSGLINE", 0, x->GetMask()); } -/* UNSZLINE */ -void bahamut::Proto::SendSZLineDel(XLine *x) +void bahamut::senders::SQLine::Send(User*, 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(), "*"); + Uplink::Send(Me, "SQLINE", x->GetMask(), x->GetReason()); +} + +void bahamut::senders::SQLineDel::Send(XLine* x) +{ + Uplink::Send("UNSQLINE", x->GetMask()); } -/* SZLINE */ -void bahamut::Proto::SendSZLine(User *, XLine *x) +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; @@ -131,130 +203,69 @@ void bahamut::Proto::SendSZLine(User *, XLine *x) Uplink::Send("AKILL", x->GetHost(), "*", timeleft, x->GetBy(), Anope::CurTime, x->GetReason()); } -/* SVSNOOP */ -void bahamut::Proto::SendSVSNOOP(Server *server, bool set) +void bahamut::senders::SZLineDel::Send(XLine* x) { - Uplink::Send("SVSNOOP", server->GetName(), set ? "+" : "-"); + /* 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(), "*"); } -/* SGLINE */ -void bahamut::Proto::SendSGLine(User *, XLine *x) +void bahamut::senders::SVSHold::Send(const Anope::string& nick, time_t t) { - Uplink::Send("SGLINE", x->GetMask().length(), x->GetMask() + ":" + x->GetReason()); + Uplink::Send(Me, "SVSHOLD", nick, t, "Being held for registered user"); } -/* RAKILL */ -void bahamut::Proto::SendAkillDel(XLine *x) +void bahamut::senders::SVSHoldDel::Send(const Anope::string& nick) { - 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("RAKKILL", x->GetHost(), x->GetUser()); + Uplink::Send(Me, "SVSHOLD", nick, 0); } -/* TOPIC */ -void bahamut::Proto::SendTopic(const MessageSource &source, Channel *c) +void bahamut::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts) { - Uplink::Send(source, "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic); + Uplink::Send("SVSNICK", u->GetUID(), newnick, ts); } -/* UNSQLINE */ -void bahamut::Proto::SendSQLineDel(XLine *x) +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("UNSQLINE", x->GetMask()); + Uplink::Send(source, "TOPIC", channel->name, topic_setter, topic_ts, topic); } -/* JOIN - SJOIN */ -void bahamut::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status) +void bahamut::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg) { - Uplink::Send(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(); - - 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); - - if (uc != NULL) - uc->status = cs; - } + Uplink::Send(source, "GLOBOPS", msg); } -void bahamut::Proto::SendAkill(User *u, XLine *x) +#warning "not used" +class ChannelModeFlood : public ChannelModeParam { - 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->GetManager()->Check(it->second, x)) - this->SendAkill(it->second, x); - return; - } - - XLine *old = x; - - 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); - - Log(Config->GetClient("OperServ"), "akill") << "AKILL: Added an akill for " << x->GetMask() << " because " << u->GetMask() << "#" << u->realname << " matches " << old->GetMask(); - } + public: + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam("FLOOD", modeChar, minusNoArg) { } - /* ZLine if we can instead */ - if (x->GetUser() == "*") + bool IsValid(Anope::string &value) const override { - cidr a(x->GetHost()); - if (a.valid()) + try { - IRCD->SendSZLine(u, x); - return; + 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; } - } - - // 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; + catch (const ConvertException &) { } - Uplink::Send("AKILL", x->GetHost(), x->GetUser(), timeleft, x->GetBy(), Anope::CurTime, x->GetReason()); -} + return false; + } +}; -/* - Note: if the stamp is null 0, the below usage is correct of Bahamut -*/ -void bahamut::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) +bahamut::Proto::Proto(Module *creator) : IRCDProto(creator, "Bahamut 1.8.x") { - Uplink::Send(source, "SVSKILL", user->nick, buf); + DefaultPseudoclientModes = "+"; + CanSVSNick = true; + CanSNLine = true; + CanSQLine = true; + CanSQLineChannel = true; + CanSZLine = true; + CanSVSHold = true; + MaxModes = 60; } void bahamut::Proto::SendBOB() @@ -267,23 +278,11 @@ void bahamut::Proto::SendEOB() Uplink::Send("BURST", 0); } -void bahamut::Proto::SendClientIntroduction(User *u) -{ - Anope::string modes = "+" + u->GetModes(); - Uplink::Send("NICK", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, u->server->GetName(), 0, 0, u->realname); -} - -/* SERVER */ -void bahamut::Proto::SendServer(Server *server) -{ - Uplink::Send("SERVER", server->GetName(), server->GetHops(), server->GetDescription()); -} - -void bahamut::Proto::SendConnect() +void bahamut::Proto::Handshake() { Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS"); Uplink::Send("CAPAB", "SSJOIN NOQUIT BURST UNCONNECT NICKIP TSMODE TS3"); - SendServer(Me); + IRCD->Send<messages::MessageServer>(Me); /* * SVINFO * parv[0] = sender prefix @@ -296,24 +295,6 @@ void bahamut::Proto::SendConnect() this->SendBOB(); } -void bahamut::Proto::SendChannel(Channel *c) -{ - Anope::string modes = c->GetModes(true, true); - if (modes.empty()) - modes = "+"; - Uplink::Send("SJOIN", c->creation_time, c->name, modes, ""); -} - -void bahamut::Proto::SendLogin(User *u, NickServ::Nick *) -{ - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", u->signon); -} - -void bahamut::Proto::SendLogout(User *u) -{ - IRCD->SendMode(Config->GetClient("NickServ"), u, "+d 1"); -} - void bahamut::Burst::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { Server *s = source.GetServer(); @@ -522,6 +503,45 @@ class ProtoBahamut : public Module 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) , EventHook<Event::UserNickChange>(this) @@ -552,13 +572,55 @@ class ProtoBahamut : public Module , 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); } }; diff --git a/modules/protocol/charybdis.cpp b/modules/protocol/charybdis.cpp index 4488f5425..a808bb594 100644 --- a/modules/protocol/charybdis.cpp +++ b/modules/protocol/charybdis.cpp @@ -23,7 +23,6 @@ #include "modules/sasl.h" #include "modules/protocol/hybrid.h" #include "modules/protocol/charybdis.h" -#include "modules/protocol/ratbox.h" #include "modules/chanserv/mode.h" static Anope::string UplinkSID; @@ -39,9 +38,57 @@ class ChannelModeLargeBan : public ChannelMode } }; +void charybdis::senders::NickIntroduction::Send(User *user) +{ + Anope::string modes = "+" + user->GetModes(); + Uplink::Send(Me, "EUID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, 0, user->GetUID(), "*", "*", user->realname); +} +void charybdis::senders::SASL::Send(const ::SASL::Message& message) +{ + Server *s = Server::Find(message.target.substr(0, 3)); + Uplink::Send(Me, "ENCAP", s ? s->GetName() : message.target.substr(0, 3), "SASL", message.source, message.target, message.type, message.data, message.ext.empty() ? "" : message.ext); +} -charybdis::Proto::Proto(Module *creator) : IRCDProto(creator, "Charybdis 3.4+") - , ratbox("ratbox") +void charybdis::senders::SASLMechanisms::Send(const std::vector<Anope::string>& mechanisms) +{ + Anope::string mechlist; + + for (unsigned int i = 0; i < mechanisms.size(); ++i) + { + mechlist += "," + mechanisms[i]; + } + + Uplink::Send(Me, "ENCAP", "*", "MECHLIST", mechlist.empty() ? "" : mechlist.substr(1)); +} + +void charybdis::senders::SVSHold::Send(const Anope::string& nick, time_t delay) +{ + Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", delay, nick); +} + +void charybdis::senders::SVSHoldDel::Send(const Anope::string& nick) +{ + Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", 0, nick); +} + +void charybdis::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost) +{ + Server *s = Server::Find(uid.substr(0, 3)); + Uplink::Send(Me, "ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, "*", vident.empty() ? "*" : vident, vhost.empty() ? "*" : vhost, acc); +} + +void charybdis::senders::VhostDel::Send(User* u) +{ + IRCD->Send<messages::VhostSet>(u, "", u->host); +} + +void charybdis::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost) +{ + Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), vhost); +} + +charybdis::Proto::Proto(Module *creator) : ts6::Proto(creator, "Charybdis 3.4+") + , ratbox(creator) { DefaultPseudoclientModes = "+oiS"; CanCertFP = true; @@ -56,7 +103,7 @@ charybdis::Proto::Proto(Module *creator) : IRCDProto(creator, "Charybdis 3.4+") MaxModes = 4; } -void charybdis::Proto::SendConnect() +void charybdis::Proto::Handshake() { Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID()); @@ -86,7 +133,7 @@ void charybdis::Proto::SendConnect() Uplink::Send("CAPAB", "BAN CHW CLUSTER ENCAP EOPMOD EUID EX IE KLN KNOCK MLOCK QS RSFNC SERVICES TB UNKLN"); /* Make myself known to myself in the serverlist */ - SendServer(Me); + Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription()); /* * Received: SVINFO 6 6 0 :1353235537 @@ -95,66 +142,9 @@ void charybdis::Proto::SendConnect() * arg[2] = '0' * arg[3] = server's idea of UTC time */ - Uplink::Send("SVINFO", 6, 6, Anope::CurTime); -} - -void charybdis::Proto::SendClientIntroduction(User *u) -{ - Anope::string modes = "+" + u->GetModes(); - Uplink::Send(Me, "EUID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, 0, u->GetUID(), "*", "*", u->realname); -} - -void charybdis::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when) -{ - Uplink::Send(Me, "ENCAP", u->server->GetName(), "RSFNC", u->GetUID(), - newnick, when, u->timestamp); + Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime); } -void charybdis::Proto::SendSVSHold(const Anope::string &nick, time_t delay) -{ - Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", delay, nick); -} - -void charybdis::Proto::SendSVSHoldDel(const Anope::string &nick) -{ - Uplink::Send(Me, "ENCAP", "*", "NICKDELAY", 0, nick); -} - -void charybdis::Proto::SendVhost(User *u, const Anope::string &ident, const Anope::string &host) -{ - Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), host); -} - -void charybdis::Proto::SendVhostDel(User *u) -{ - this->SendVhost(u, "", u->host); -} - -void charybdis::Proto::SendSASLMechanisms(std::vector<Anope::string> &mechanisms) -{ - Anope::string mechlist; - - for (unsigned i = 0; i < mechanisms.size(); ++i) - { - mechlist += "," + mechanisms[i]; - } - - Uplink::Send(Me, "ENCAP", "*", "MECHLIST", mechlist.empty() ? "" : mechlist.substr(1)); -} - -void charybdis::Proto::SendSASLMessage(const SASL::Message &message) -{ - Server *s = Server::Find(message.target.substr(0, 3)); - Uplink::Send(Me, "ENCAP", s ? s->GetName() : message.target.substr(0, 3), "SASL", message.source, message.target, message.type, message.data, message.ext.empty() ? "" : message.ext); -} - -void charybdis::Proto::SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) -{ - Server *s = Server::Find(uid.substr(0, 3)); - Uplink::Send(Me, "ENCAP", s ? s->GetName() : uid.substr(0, 3), "SVSLOGIN", uid, "*", vident.empty() ? "*" : vident, vhost.empty() ? "*" : vhost, acc); -} - - void charybdis::Encap::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { // In a burst, states that the source user is logged in as the account. @@ -228,7 +218,7 @@ void charybdis::ServerMessage::Run(MessageSource &source, const std::vector<Anop if (params[1] != "1") return; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send<messages::Ping>(Me->GetName(), params[0]); } // we can't use this function from ratbox because we set a local variable here @@ -282,6 +272,48 @@ class ProtoCharybdis : public Module hybrid::TMode message_tmode; ratbox::UID message_uid; + /* Core message senders */ + rfc1459::senders::Invite sender_invite; + rfc1459::senders::Kick sender_kick; + rfc1459::senders::Kill sender_svskill; + rfc1459::senders::ModeChannel sender_mode_chan; + rfc1459::senders::ModeUser sender_mode_user; + 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; + + hybrid::senders::Akill sender_akill; + hybrid::senders::AkillDel sender_akill_del; + hybrid::senders::MessageChannel sender_channel; + hybrid::senders::GlobalNotice sender_global_notice; + hybrid::senders::GlobalPrivmsg sender_global_privmsg; + hybrid::senders::Join sender_join; + hybrid::senders::MessageServer sender_server; + hybrid::senders::SGLine sender_sgline; + hybrid::senders::SGLineDel sender_sgline_del; + hybrid::senders::SVSHold sender_svshold; + hybrid::senders::SVSHoldDel sender_svsholddel; + + ratbox::senders::Login sender_login; + ratbox::senders::Logout sender_logout; + ratbox::senders::SQLine sender_sqline; + ratbox::senders::SQLineDel sender_sqline_del; + ratbox::senders::SVSNick sender_svsnick; + ratbox::senders::Topic sender_topic; + ratbox::senders::Wallops sender_wallops; + + charybdis::senders::NickIntroduction sender_nickintroduction; + charybdis::senders::SASL sender_sasl; + charybdis::senders::SASLMechanisms sender_sasl_mechs; + charybdis::senders::SVSLogin sender_svslogin; + charybdis::senders::VhostDel sender_vhost_del; + charybdis::senders::VhostSet sender_vhost_set; + bool use_server_side_mlock; public: @@ -322,7 +354,51 @@ class ProtoCharybdis : public Module , message_tb(this) , message_tmode(this) , message_uid(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_notice(this) + , sender_part(this) + , sender_ping(this) + , sender_pong(this) + , sender_privmsg(this) + , sender_quit(this) + , sender_server(this) + , sender_sasl(this) + , sender_sasl_mechs(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_svslogin(this) + , sender_svsnick(this) + , sender_topic(this) + , sender_vhost_del(this) + , sender_vhost_set(this) + , sender_wallops(this) + { + IRCD = &ircd_proto; + } + + ~ProtoCharybdis() { + IRCD = nullptr; } void OnReload(Configuration::Conf *conf) override diff --git a/modules/protocol/hybrid.cpp b/modules/protocol/hybrid.cpp index 922083587..2cb508f0e 100644 --- a/modules/protocol/hybrid.cpp +++ b/modules/protocol/hybrid.cpp @@ -18,134 +18,14 @@ * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ -/* Dependencies: anope_protocol.rfc1459 */ +/* Dependencies: anope_protocol.rfc1459,anope_protocol.ts6 */ #include "module.h" #include "modules/protocol/hybrid.h" static Anope::string UplinkSID; - -ServiceBot *hybrid::Proto::FindIntroduced() -{ - ServiceBot *bi = Config->GetClient("OperServ"); - if (bi && bi->introduced) - return bi; - - for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) - { - User *u = it->second; - if (u->type == UserType::BOT) - { - bi = anope_dynamic_static_cast<ServiceBot *>(u); - if (bi->introduced) - return bi; - } - } - - return NULL; -} - -void hybrid::Proto::SendSVSKill(const MessageSource &source, User *u, const Anope::string &buf) -{ - IRCDProto::SendSVSKill(source, u, buf); - u->KillInternal(source, buf); -} - -hybrid::Proto::Proto(Module *creator) : IRCDProto(creator, "Hybrid 8.2.x") -{ - DefaultPseudoclientModes = "+oi"; - CanSVSNick = true; - CanSVSHold = true; - CanSVSJoin = true; - CanSNLine = true; - CanSQLine = true; - CanSQLineChannel = true; - CanSZLine = true; - CanCertFP = true; - CanSetVHost = true; - RequiresID = true; - MaxModes = 6; -} - -void hybrid::Proto::SendInvite(const MessageSource &source, Channel *c, User *u) -{ - Uplink::Send(source, "INVITE", u->GetUID(), c->name, c->creation_time); -} - -void hybrid::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "NOTICE", "$$" + dest->GetName(), msg); -} - -void hybrid::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "PRIVMSG", "$$" + dest->GetName(), msg); -} - -void hybrid::Proto::SendSQLine(User *, XLine *x) -{ - Uplink::Send(FindIntroduced(), "RESV", "*", x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetMask(), x->GetReason()); -} - -void hybrid::Proto::SendSGLineDel(XLine *x) -{ - Uplink::Send(Config->GetClient("OperServ"), "UNXLINE", "*", x->GetMask()); -} - -void hybrid::Proto::SendSGLine(User *, XLine *x) -{ - Uplink::Send(Config->GetClient("OperServ"), "XLINE", "*", x->GetMask(), x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetReason()); -} - -void hybrid::Proto::SendSZLineDel(XLine *x) -{ - Uplink::Send(Config->GetClient("OperServ"), "UNDLINE", "*", x->GetHost()); -} - -void hybrid::Proto::SendSZLine(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; - - Uplink::Send(Config->GetClient("OperServ"), "DLINE", "*", timeleft, x->GetHost(), x->GetReason()); -} - -void hybrid::Proto::SendAkillDel(XLine *x) -{ - if (x->IsRegex() || x->HasNickOrReal()) - return; - - Uplink::Send(Config->GetClient("OperServ"), "UNKLINE", "*", x->GetUser(), x->GetHost()); -} - -void hybrid::Proto::SendSQLineDel(XLine *x) -{ - Uplink::Send(Config->GetClient("OperServ"), "UNRESV", "*", x->GetMask()); -} - -void hybrid::Proto::SendJoin(User *u, Channel *c, const ChannelStatus *status) -{ - /* - * Note that we must send our modes with the SJOIN and can not add them to the - * mode stacker because ircd-hybrid does not allow *any* client to op itself - */ - Uplink::Send("SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), (status != NULL ? status->BuildModePrefixList() : "") + u->GetUID()); - - /* And update our internal status for this user since this is not going through our mode handling system */ - if (status) - { - ChanUserContainer *uc = c->FindUser(u); - - if (uc) - uc->status = *status; - } -} - -void hybrid::Proto::SendAkill(User *u, XLine *x) +void hybrid::senders::Akill::Send(User* u, XLine* x) { if (x->IsRegex() || x->HasNickOrReal()) { @@ -157,7 +37,7 @@ void hybrid::Proto::SendAkill(User *u, XLine *x) */ 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; } @@ -191,111 +71,132 @@ void hybrid::Proto::SendAkill(User *u, XLine *x) Uplink::Send(Config->GetClient("OperServ"), "KLINE", timeleft, x->GetUser(), x->GetHost(), x->GetReason()); } -void hybrid::Proto::SendServer(Server *server) +void hybrid::senders::AkillDel::Send(XLine* x) { - if (server == Me) - Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription()); - else - Uplink::Send(Me, "SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription()); + if (x->IsRegex() || x->HasNickOrReal()) + return; + + Uplink::Send(Config->GetClient("OperServ"), "UNKLINE", "*", x->GetUser(), x->GetHost()); } -void hybrid::Proto::SendConnect() +void hybrid::senders::MessageChannel::Send(Channel* c) { - Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID()); - - /* - * As of January 13, 2016, ircd-hybrid-8 supports the following capabilities - * which are required to work with IRC-services: - * - * QS - Can handle quit storm removal - * EX - Can do channel +e exemptions - * IE - Can do invite exceptions - * CHW - Can do channel wall @# - * TBURST - Supports topic burst - * ENCAP - Supports ENCAP - * HOPS - Supports HalfOps - * SVS - Supports services - * EOB - Supports End Of Burst message - */ - Uplink::Send("CAPAB", "QS EX CHW IE ENCAP TBURST SVS HOPS EOB"); + Anope::string modes = c->GetModes(true, true); - SendServer(Me); + if (modes.empty()) + modes = "+"; - Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime); + Uplink::Send("SJOIN", c->creation_time, c->name, modes, ""); } -void hybrid::Proto::SendClientIntroduction(User *u) +void hybrid::senders::GlobalNotice::Send(const MessageSource &source, Server *dest, const Anope::string &msg) { - Anope::string modes = "+" + u->GetModes(); + Uplink::Send(source, "NOTICE", "$$" + dest->GetName(), msg); +} - Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, "0.0.0.0", u->GetUID(), "*", u->realname); +void hybrid::senders::GlobalPrivmsg::Send(const MessageSource& source, Server* dest, const Anope::string& msg) +{ + Uplink::Send(source, "PRIVMSG", "$$" + dest->GetName(), msg); } -void hybrid::Proto::SendEOB() +void hybrid::senders::Invite::Send(const MessageSource &source, Channel *chan, User *user) { - Uplink::Send(Me, "EOB"); + Uplink::Send(source, "INVITE", user->GetUID(), chan->name, chan->creation_time); } -void hybrid::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf) +void hybrid::senders::Join::Send(User* u, Channel* c, const ChannelStatus* status) { - IRCMessage message(source, "SVSMODE", u->GetUID(), u->timestamp); - message.TokenizeAndPush(buf); - Uplink::SendMessage(message); + /* + * Note that we must send our modes with the SJOIN and can not add them to the + * mode stacker because ircd-hybrid does not allow *any* client to op itself + */ + Uplink::Send("SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), (status != NULL ? status->BuildModePrefixList() : "") + u->GetUID()); + + /* And update our internal status for this user since this is not going through our mode handling system */ + if (status) + { + ChanUserContainer *uc = c->FindUser(u); + + if (uc) + uc->status = *status; + } } -void hybrid::Proto::SendLogin(User *u, NickServ::Nick *na) +void hybrid::senders::Login::Send(User *u, NickServ::Nick *na) { IRCD->SendMode(Config->GetClient("NickServ"), u, "+d {0}", na->GetAccount()->GetDisplay()); } -void hybrid::Proto::SendLogout(User *u) +void hybrid::senders::Logout::Send(User *u) { IRCD->SendMode(Config->GetClient("NickServ"), u, "+d *"); } -void hybrid::Proto::SendChannel(Channel *c) +void hybrid::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes) { - Anope::string modes = c->GetModes(true, true); + IRCMessage message(source, "SVSMODE", user->GetUID(), user->timestamp); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); +} - if (modes.empty()) - modes = "+"; +void hybrid::senders::NickIntroduction::Send(User *user) +{ + Anope::string modes = "+" + user->GetModes(); + Uplink::Send(Me, "UID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, "0.0.0.0", user->GetUID(), "*", user->realname); +} - Uplink::Send("SJOIN", c->creation_time, c->name, modes, ""); +void hybrid::senders::MessageServer::Send(Server* server) +{ + Uplink::Send(Me, "SID", server->GetName(), server->GetHops() + 1, server->GetSID(), server->GetDescription()); +} + +void hybrid::senders::SGLine::Send(User*, XLine* x) +{ + Uplink::Send(Config->GetClient("OperServ"), "XLINE", "*", x->GetMask(), x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetReason()); } -void hybrid::Proto::SendTopic(const MessageSource &source, Channel *c) +void hybrid::senders::SGLineDel::Send(XLine* x) { - Uplink::Send(source, "TBURST", c->creation_time, c->name, c->topic_ts, c->topic_setter, c->topic); + Uplink::Send(Config->GetClient("OperServ"), "UNXLINE", "*", x->GetMask()); } -void hybrid::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when) +void hybrid::senders::SQLine::Send(User*, XLine* x) { - Uplink::Send(Me, "SVSNICK", u->GetUID(), newnick, when); +#warning "findintroduced" + //Uplink::Send(FindIntroduced(), "RESV", "*", x->GetExpires() ? x->GetExpires() - Anope::CurTime : 0, x->GetMask(), x->GetReason()); } -void hybrid::Proto::SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) +void hybrid::senders::SQLineDel::Send(XLine* x) { - Uplink::Send(source, "SVSJOIN", u->GetUID(), chan); + Uplink::Send(Config->GetClient("OperServ"), "UNRESV", "*", x->GetMask()); } -void hybrid::Proto::SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) +void hybrid::senders::SZLine::Send(User*, XLine* x) { - if (!param.empty()) - Uplink::Send(source, "SVSPART", u->GetUID(), chan, param); - else - Uplink::Send(source, "SVSPART", u->GetUID(), chan); + /* 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; + + Uplink::Send(Config->GetClient("OperServ"), "DLINE", "*", timeleft, x->GetHost(), x->GetReason()); } -void hybrid::Proto::SendSVSHold(const Anope::string &nick, time_t t) +void hybrid::senders::SZLineDel::Send(XLine* x) +{ + Uplink::Send(Config->GetClient("OperServ"), "UNDLINE", "*", x->GetHost()); +} + +void hybrid::senders::SVSHold::Send(const Anope::string&, time_t) { #if 0 XLine x(nick, Me->GetName(), Anope::CurTime + t, "Being held for registered user"); this->SendSQLine(NULL, &x); #endif } -#warning "xline on stack" -void hybrid::Proto::SendSVSHoldDel(const Anope::string &nick) +#warning "xline on stack" +void hybrid::senders::SVSHoldDel::Send(const Anope::string&) { #if 0 XLine x(nick); @@ -303,19 +204,113 @@ void hybrid::Proto::SendSVSHoldDel(const Anope::string &nick) #endif } -void hybrid::Proto::SendVhost(User *u, const Anope::string &ident, const Anope::string &host) +void hybrid::senders::SVSJoin::Send(const MessageSource& source, User* u, const Anope::string& chan, const Anope::string& key) +{ + Uplink::Send(source, "SVSJOIN", u->GetUID(), chan); +} + +void hybrid::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts) { - u->SetMode(Config->GetClient("HostServ"), "CLOAK", host); + Uplink::Send(Me, "SVSNICK", u->GetUID(), newnick, ts); } -void hybrid::Proto::SendVhostDel(User *u) +void hybrid::senders::SVSPart::Send(const MessageSource& source, User* u, const Anope::string& chan, const Anope::string& reason) +{ + if (!reason.empty()) + Uplink::Send(source, "SVSPART", u->GetUID(), chan, reason); + else + Uplink::Send(source, "SVSPART", u->GetUID(), chan); +} + +void hybrid::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) +{ + Uplink::Send(source, "TBURST", channel->creation_time, channel->name, topic_ts, topic_setter, topic); +} + +void hybrid::senders::VhostDel::Send(User* u) { u->RemoveMode(Config->GetClient("HostServ"), "CLOAK", u->host); } +void hybrid::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost) +{ + u->SetMode(Config->GetClient("HostServ"), "CLOAK", vhost); +} + +void hybrid::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg) +{ + Uplink::Send(source, "GLOBOPS", msg); +} + +ServiceBot *hybrid::Proto::FindIntroduced() +{ + ServiceBot *bi = Config->GetClient("OperServ"); + if (bi && bi->introduced) + return bi; + + for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it) + { + User *u = it->second; + if (u->type == UserType::BOT) + { + bi = anope_dynamic_static_cast<ServiceBot *>(u); + if (bi->introduced) + return bi; + } + } + + return NULL; +} + +hybrid::Proto::Proto(Module *creator) : ts6::Proto(creator, "Hybrid 8.2.x") +{ + DefaultPseudoclientModes = "+oi"; + CanSVSNick = true; + CanSVSHold = true; + CanSVSJoin = true; + CanSNLine = true; + CanSQLine = true; + CanSQLineChannel = true; + CanSZLine = true; + CanCertFP = true; + CanSetVHost = true; + RequiresID = true; + MaxModes = 6; +} + +void hybrid::Proto::Handshake() +{ + Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID()); + + /* + * As of January 13, 2016, ircd-hybrid-8 supports the following capabilities + * which are required to work with IRC-services: + * + * QS - Can handle quit storm removal + * EX - Can do channel +e exemptions + * IE - Can do invite exceptions + * CHW - Can do channel wall @# + * TBURST - Supports topic burst + * ENCAP - Supports ENCAP + * HOPS - Supports HalfOps + * SVS - Supports services + * EOB - Supports End Of Burst message + */ + Uplink::Send("CAPAB", "QS EX CHW IE ENCAP TBURST SVS HOPS EOB"); + + Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription()); + + Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime); +} + +void hybrid::Proto::SendEOB() +{ + Uplink::Send(Me, "EOB"); +} + bool hybrid::Proto::IsIdentValid(const Anope::string &ident) { - if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen")) + if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned int>("userlen")) return false; Anope::string chars = "~}|{ `_^]\\[ .-$"; @@ -410,7 +405,7 @@ void hybrid::ServerMessage::Run(MessageSource &source, const std::vector<Anope:: new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send<messages::Ping>(Me->GetName(), params[0]); } void hybrid::SID::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) @@ -425,7 +420,7 @@ void hybrid::SID::Run(MessageSource &source, const std::vector<Anope::string> &p new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[3], params[2]); - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send<messages::Ping>(Me->GetName(), params[0]); } void hybrid::SJoin::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) @@ -621,6 +616,45 @@ class ProtoHybrid : public Module hybrid::TMode message_tmode; hybrid::UID message_uid; + /* Core message senders */ + rfc1459::senders::Kick sender_kick; + rfc1459::senders::Kill sender_svskill; + 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; + + hybrid::senders::Akill sender_akill; + hybrid::senders::AkillDel sender_akill_del; + hybrid::senders::MessageChannel sender_channel; + hybrid::senders::GlobalNotice sender_global_notice; + hybrid::senders::GlobalPrivmsg sender_global_privmsg; + hybrid::senders::Invite sender_invite; + hybrid::senders::Join sender_join; + hybrid::senders::Login sender_login; + hybrid::senders::Logout sender_logout; + hybrid::senders::ModeUser sender_mode_user; + hybrid::senders::NickIntroduction sender_nickintroduction; + hybrid::senders::MessageServer sender_server; + hybrid::senders::SGLine sender_sgline; + hybrid::senders::SGLineDel sender_sgline_del; + hybrid::senders::SQLine sender_sqline; + hybrid::senders::SQLineDel sender_sqline_del; + hybrid::senders::SZLine sender_szline; + hybrid::senders::SZLineDel sender_szline_del; + hybrid::senders::SVSHold sender_svshold; + hybrid::senders::SVSHoldDel sender_svsholddel; + hybrid::senders::SVSNick sender_svsnick; + hybrid::senders::Topic sender_topic; + hybrid::senders::VhostDel sender_vhost_del; + hybrid::senders::VhostSet sender_vhost_set; + hybrid::senders::Wallops sender_wallops; + public: ProtoHybrid(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , EventHook<Event::UserNickChange>(this) @@ -658,7 +692,50 @@ public: , message_tmode(this) , message_uid(this) , message_certfp(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_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_topic(this) + , sender_vhost_del(this) + , sender_vhost_set(this) + , sender_wallops(this) + { + IRCD = &ircd_proto; + } + + ~ProtoHybrid() { + IRCD = nullptr; } void OnUserNickChange(User *u, const Anope::string &) override diff --git a/modules/protocol/inspircd20.cpp b/modules/protocol/inspircd20.cpp index a8caac27a..011ecfd13 100644 --- a/modules/protocol/inspircd20.cpp +++ b/modules/protocol/inspircd20.cpp @@ -17,7 +17,7 @@ * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ -/* Dependencies: anope_protocol.rfc1459 */ +/* Dependencies: anope_protocol.rfc1459,anope_protocol.ts6,anope_protocol.hybrid,anope_protocol.bahamut */ #include "module.h" #include "modules/sasl.h" @@ -25,6 +25,8 @@ #include "modules/chanserv/set.h" #include "modules/protocol/rfc1459.h" #include "modules/protocol/inspircd20.h" +#include "modules/protocol/bahamut.h" +#include "modules/protocol/hybrid.h" struct SASLUser { @@ -37,129 +39,7 @@ static std::list<SASLUser> saslusers; static Anope::string rsquit_server, rsquit_id; static unsigned int spanningtree_proto_ver = 0; -void inspircd20::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) -{ - IRCDProto::SendSVSKill(source, user, buf); - user->KillInternal(source, buf); -} - -void inspircd20::Proto::SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent) -{ - if (!Servers::Capab.count("CHGIDENT")) - Log() << "CHGIDENT not loaded!"; - else - Uplink::Send(Me, "CHGIDENT", nick, vIdent); -} - -void inspircd20::Proto::SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost) -{ - if (!Servers::Capab.count("CHGHOST")) - Log() << "CHGHOST not loaded!"; - else - Uplink::Send(Me, "CHGHOST", nick, vhost); -} - -void inspircd20::Proto::SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason) -{ - Uplink::Send(Me, "ADDLINE", xtype, mask, addedby, Anope::CurTime, duration, reason); -} - -void inspircd20::Proto::SendDelLine(const Anope::string &xtype, const Anope::string &mask) -{ - Uplink::Send(Me, "DELLINE", xtype, mask); -} - -inspircd20::Proto::Proto(Module *creator) : IRCDProto(creator, "InspIRCd 2.0") -{ - DefaultPseudoclientModes = "+I"; - CanSVSNick = true; - CanSVSJoin = true; - CanSetVHost = true; - CanSetVIdent = true; - CanSQLine = true; - CanSZLine = true; - CanSVSHold = true; - CanCertFP = true; - RequiresID = true; - MaxModes = 20; -} - -void inspircd20::Proto::SendConnect() -{ - Uplink::Send("CAPAB START 1202"); - Uplink::Send("CAPAB CAPABILITIES :PROTOCOL=1202"); - Uplink::Send("CAPAB END"); - SendServer(Me); -} - -void inspircd20::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg); -} - -void inspircd20::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg); -} - -void inspircd20::Proto::SendAkillDel(XLine *x) -{ - /* InspIRCd may support regex bans */ - if (x->IsRegex() && Servers::Capab.count("RLINE")) - { - Anope::string mask = x->GetMask(); - size_t h = mask.find('#'); - if (h != Anope::string::npos) - mask = mask.replace(h, 1, ' '); - SendDelLine("R", mask); - return; - } - else if (x->IsRegex() || x->HasNickOrReal()) - return; - - /* ZLine if we can instead */ - if (x->GetUser() == "*") - { - cidr addr(x->GetHost()); - if (addr.valid()) - { - IRCD->SendSZLineDel(x); - return; - } - } - - SendDelLine("G", x->GetUser() + "@" + x->GetHost()); -} - -void inspircd20::Proto::SendTopic(const MessageSource &source, Channel *c) -{ - if (Servers::Capab.count("SVSTOPIC")) - { - Uplink::Send(c->ci->WhoSends(), "SVSTOPIC", c->name, c->topic_ts, c->topic_setter, c->topic); - } - else - { - /* If the last time a topic was set is after the TS we want for this topic we must bump this topic's timestamp to now */ - time_t ts = c->topic_ts; - if (c->topic_time > ts) - ts = Anope::CurTime; - /* But don't modify c->topic_ts, it should remain set to the real TS we want as ci->last_topic_time pulls from it */ - Uplink::Send(source, "FTOPIC", c->name, ts, c->topic_setter, c->topic); - } -} - -void inspircd20::Proto::SendVhostDel(User *u) -{ - if (u->HasMode("CLOAK")) - this->SendChgHostInternal(u->nick, u->chost); - else - this->SendChgHostInternal(u->nick, u->host); - - if (Servers::Capab.count("CHGIDENT") && u->GetIdent() != u->GetVIdent()) - this->SendChgIdentInternal(u->nick, u->GetIdent()); -} - -void inspircd20::Proto::SendAkill(User *u, XLine *x) +void inspircd20::senders::Akill::Send(User* u, XLine* x) { // Calculate the time left before this would expire, capping it at 2 days time_t timeleft = x->GetExpires() - Anope::CurTime; @@ -173,7 +53,7 @@ void inspircd20::Proto::SendAkill(User *u, XLine *x) size_t h = mask.find('#'); if (h != Anope::string::npos) mask = mask.replace(h, 1, ' '); - SendAddLine("R", mask, timeleft, x->GetBy(), x->GetReason()); + proto->SendAddLine("R", mask, timeleft, x->GetBy(), x->GetReason()); return; } else if (x->IsRegex() || x->HasNickOrReal()) @@ -183,7 +63,7 @@ void inspircd20::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; } @@ -209,70 +89,49 @@ void inspircd20::Proto::SendAkill(User *u, XLine *x) cidr addr(x->GetHost()); if (addr.valid()) { - IRCD->SendSZLine(u, x); + IRCD->Send<messages::SZLine>(u, x); return; } } - SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->GetBy(), x->GetReason()); + proto->SendAddLine("G", x->GetUser() + "@" + x->GetHost(), timeleft, x->GetBy(), x->GetReason()); } -void inspircd20::Proto::SendNumeric(int numeric, User *dest, IRCMessage &message) +void inspircd20::senders::AkillDel::Send(XLine* x) { - std::vector<Anope::string> params = message.GetParameters(); - if (params.empty()) + /* InspIRCd may support regex bans */ + if (x->IsRegex() && Servers::Capab.count("RLINE")) + { + Anope::string mask = x->GetMask(); + size_t h = mask.find('#'); + if (h != Anope::string::npos) + mask = mask.replace(h, 1, ' '); + proto->SendDelLine("R", mask); + return; + } + else if (x->IsRegex() || x->HasNickOrReal()) return; - /* First parameter is the UID, change it to nick because it is pushed */ - params[0] = dest->nick; - - IRCMessage m(message.GetSource(), message.GetCommand()); - for (const Anope::string &s : params) - m.Push(s); - - Uplink::Send("PUSH", dest->GetUID(), Format(m)); -} - -void inspircd20::Proto::SendMode(const MessageSource &source, Channel *dest, const Anope::string &buf) -{ - IRCMessage message(source, "FMODE", dest->name, dest->creation_time); - message.TokenizeAndPush(buf); - Uplink::SendMessage(message); -} - -void inspircd20::Proto::SendClientIntroduction(User *u) -{ - Anope::string modes = "+" + u->GetModes(); - Uplink::Send(Me, "UID", u->GetUID(), u->timestamp, u->nick, u->host, u->host, u->GetIdent(), "0.0.0.0", u->timestamp, modes, u->realname); - if (modes.find('o') != Anope::string::npos) - Uplink::Send(u, "OPERTYPE", "services"); -} + /* ZLine if we can instead */ + if (x->GetUser() == "*") + { + cidr addr(x->GetHost()); + if (addr.valid()) + { + IRCD->Send<messages::SZLineDel>(x); + return; + } + } -/* SERVER services-dev.chatspike.net password 0 :Description here */ -void inspircd20::Proto::SendServer(Server *server) -{ - /* if rsquit is set then we are waiting on a squit */ - if (rsquit_id.empty() && rsquit_server.empty()) - Uplink::Send("SERVER", server->GetName(), Config->Uplinks[Anope::CurrentUplink].password, server->GetHops(), server->GetSID(), server->GetDescription()); + proto->SendDelLine("G", x->GetUser() + "@" + x->GetHost()); } -void inspircd20::Proto::SendSquit(Server *s, const Anope::string &message) +void inspircd20::senders::MessageChannel::Send(Channel* c) { - if (s != Me) - { - rsquit_id = s->GetSID(); - rsquit_server = s->GetName(); - - Uplink::Send("RSQUIT", s->GetName(), message); - } - else - { - Uplink::Send("SQUIT", s->GetName(), message); - } + Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), ""); } -/* JOIN */ -void inspircd20::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status) +void inspircd20::senders::Join::Send(User* user, Channel* c, const ChannelStatus* status) { Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), "," + user->GetUID()); @@ -300,159 +159,264 @@ void inspircd20::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *st } } -/* UNSQLINE */ -void inspircd20::Proto::SendSQLineDel(XLine *x) +void inspircd20::senders::Login::Send(User *u, NickServ::Nick *na) { - SendDelLine("Q", x->GetMask()); + /* InspIRCd uses an account to bypass chmode +R, not umode +r, so we can't send this here */ + if (na->GetAccount()->IsUnconfirmed()) + return; + + Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay()); } -/* SQLINE */ -void inspircd20::Proto::SendSQLine(User *, XLine *x) +void inspircd20::senders::Logout::Send(User *u) { - // 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; - SendAddLine("Q", x->GetMask(), timeleft, x->GetBy(), x->GetReason()); + Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", ""); } -void inspircd20::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) +void inspircd20::senders::ModeChannel::Send(const MessageSource &source, Channel *channel, const Anope::string &modes) { - if (!vIdent.empty()) - this->SendChgIdentInternal(u->nick, vIdent); - if (!vhost.empty()) - this->SendChgHostInternal(u->nick, vhost); + IRCMessage message(source, "FMODE", channel->name, channel->creation_time); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); } -/* SVSHOLD - set */ -void inspircd20::Proto::SendSVSHold(const Anope::string &nick, time_t t) +void inspircd20::senders::NickIntroduction::Send(User *user) { - Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick, t, "Being held for registered user"); + Anope::string modes = "+" + user->GetModes(); + Uplink::Send(Me, "UID", user->GetUID(), user->timestamp, user->nick, user->host, user->host, user->GetIdent(), "0.0.0.0", user->timestamp, modes, user->realname); + if (modes.find('o') != Anope::string::npos) + Uplink::Send(user, "OPERTYPE", "services"); } -/* SVSHOLD - release */ -void inspircd20::Proto::SendSVSHoldDel(const Anope::string &nick) + +void inspircd20::senders::SASL::Send(const ::SASL::Message& message) { - Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick); + if (!message.ext.empty()) + Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL", + message.source, message.target, + message.type, message.data, message.ext); + else + Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL", + message.source, message.target, + message.type, message.data); } -/* UNSZLINE */ -void inspircd20::Proto::SendSZLineDel(XLine *x) +void inspircd20::senders::SASLMechanisms::Send(const std::vector<Anope::string>& mechanisms) { - SendDelLine("Z", x->GetHost()); + Anope::string mechlist; + for (unsigned int i = 0; i < mechanisms.size(); ++i) + mechlist += "," + mechanisms[i]; + + Uplink::Send(Me, "METADATA", "*", "saslmechlist", mechlist.empty() ? "" : mechlist.substr(1)); +} + +void inspircd20::senders::MessageServer::Send(Server* server) +{ + /* if rsquit is set then we are waiting on a squit */ + if (rsquit_id.empty() && rsquit_server.empty()) + Uplink::Send("SERVER", server->GetName(), Config->Uplinks[Anope::CurrentUplink].password, server->GetHops(), server->GetSID(), server->GetDescription()); } -/* SZLINE */ -void inspircd20::Proto::SendSZLine(User *, XLine *x) +void inspircd20::senders::SQLine::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; - SendAddLine("Z", x->GetHost(), timeleft, x->GetBy(), x->GetReason()); + proto->SendAddLine("Q", x->GetMask(), timeleft, x->GetBy(), x->GetReason()); } -void inspircd20::Proto::SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) +void inspircd20::senders::SQLineDel::Send(XLine* x) { - Uplink::Send(source, "SVSJOIN", u->GetUID(), chan); + proto->SendDelLine("Q", x->GetMask()); } -void inspircd20::Proto::SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) +void inspircd20::senders::SQuit::Send(Server *s, const Anope::string &message) { - if (!param.empty()) - Uplink::Send(source, "SVSPART", u->GetUID(), chan, param); + if (s != Me) + { + rsquit_id = s->GetSID(); + rsquit_server = s->GetName(); + + Uplink::Send("RSQUIT", s->GetName(), message); + } else - Uplink::Send(source, "SVSPART", u->GetUID(), chan); + { + Uplink::Send("SQUIT", s->GetName(), message); + } } -void inspircd20::Proto::SendSWhois(const MessageSource &, const Anope::string &who, const Anope::string &mask) +void inspircd20::senders::SZLine::Send(User*, XLine* x) { - User *u = User::Find(who); + // 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; + proto->SendAddLine("Z", x->GetHost(), timeleft, x->GetBy(), x->GetReason()); +} - Uplink::Send(Me, "METADATA", u->GetUID(), "swhois", mask); +void inspircd20::senders::SZLineDel::Send(XLine* x) +{ + proto->SendDelLine("Z", x->GetHost()); } -void inspircd20::Proto::SendBOB() +void inspircd20::senders::SVSHold::Send(const Anope::string& nick, time_t t) { - Uplink::Send(Me, "BURST", Anope::CurTime); - Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - Uplink::Send(Me, "VERSION", Anope::Format("Anope-{0} {1} {2} - {3} - Built: {4} - Flags: {5}", - Anope::Version(), Me->GetName(), IRCD->GetProtocolName(), enc ? enc->name : "(none)", Anope::VersionBuildTime(), Anope::VersionFlags())); + Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick, t, "Being held for registered user"); } -void inspircd20::Proto::SendEOB() +void inspircd20::senders::SVSHoldDel::Send(const Anope::string& nick) { - Uplink::Send(Me, "ENDBURST"); + Uplink::Send(Config->GetClient("NickServ"), "SVSHOLD", nick); } -void inspircd20::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf) +void inspircd20::senders::SVSLogin::Send(const Anope::string& uid, const Anope::string& acc, const Anope::string& vident, const Anope::string& vhost) { - if (Servers::Capab.count("GLOBOPS")) - Uplink::Send(source, "SNONOTICE", "g", buf); - else - Uplink::Send(source, "SNONOTICE", "A", buf); + Uplink::Send(Me, "METADATA", uid, "accountname", acc); + + SASLUser su; + su.uid = uid; + su.acc = acc; + su.created = Anope::CurTime; + + for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();) + { + SASLUser &u = *it; + + if (u.created + 30 < Anope::CurTime || u.uid == uid) + it = saslusers.erase(it); + else + ++it; + } + + saslusers.push_back(su); } -void inspircd20::Proto::SendLogin(User *u, NickServ::Nick *na) +void inspircd20::senders::SWhois::Send(const MessageSource&, User *user, const Anope::string& swhois) { - /* InspIRCd uses an account to bypass chmode +R, not umode +r, so we can't send this here */ - if (na->GetAccount()->IsUnconfirmed()) - return; + Uplink::Send(Me, "METADATA", user->GetUID(), "swhois", swhois); +} - Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay()); +void inspircd20::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) +{ + if (Servers::Capab.count("SVSTOPIC")) + { + Uplink::Send(source, "SVSTOPIC", channel->name, topic_ts, topic_setter, topic); + } + else + { + /* If the last time a topic was set is after the TS we want for this topic we must bump this topic's timestamp to now */ + time_t ts = topic_ts; + if (channel->topic_time > ts) + ts = Anope::CurTime; + /* But don't modify c->topic_ts, it should remain set to the real TS we want as ci->last_topic_time pulls from it */ + Uplink::Send(source, "FTOPIC", channel->name, ts, topic_setter, topic); + } } -void inspircd20::Proto::SendLogout(User *u) +void inspircd20::senders::VhostDel::Send(User* u) { - Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", ""); + if (u->HasMode("CLOAK")) + proto->SendChgHostInternal(u->nick, u->chost); + else + proto->SendChgHostInternal(u->nick, u->host); + + if (Servers::Capab.count("CHGIDENT") && u->GetIdent() != u->GetVIdent()) + proto->SendChgIdentInternal(u->nick, u->GetIdent()); } -void inspircd20::Proto::SendChannel(Channel *c) +void inspircd20::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost) { - Uplink::Send(Me, "FJOIN", c->name, c->creation_time, "+" + c->GetModes(true, true), ""); + if (!vident.empty()) + proto->SendChgIdentInternal(u->nick, vident); + if (!vhost.empty()) + proto->SendChgHostInternal(u->nick, vhost); } -void inspircd20::Proto::SendSASLMechanisms(std::vector<Anope::string> &mechanisms) +void inspircd20::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg) { - Anope::string mechlist; - for (unsigned i = 0; i < mechanisms.size(); ++i) - mechlist += "," + mechanisms[i]; + if (Servers::Capab.count("GLOBOPS")) + Uplink::Send(source, "SNONOTICE", "g", msg); + else + Uplink::Send(source, "SNONOTICE", "A", msg); +} - Uplink::Send(Me, "METADATA", "*", "saslmechlist", mechlist.empty() ? "" : mechlist.substr(1)); +void inspircd20::Proto::SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent) +{ + if (!Servers::Capab.count("CHGIDENT")) + Log() << "CHGIDENT not loaded!"; + else + Uplink::Send(Me, "CHGIDENT", nick, vIdent); } -void inspircd20::Proto::SendSASLMessage(const SASL::Message &message) +void inspircd20::Proto::SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost) { - if (!message.ext.empty()) - Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL", - message.source, message.target, - message.type, message.data, message.ext); + if (!Servers::Capab.count("CHGHOST")) + Log() << "CHGHOST not loaded!"; else - Uplink::Send(Me, "ENCAP", message.target.substr(0, 3), "SASL", - message.source, message.target, - message.type, message.data); + Uplink::Send(Me, "CHGHOST", nick, vhost); } -void inspircd20::Proto::SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) +void inspircd20::Proto::SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason) { - Uplink::Send(Me, "METADATA", uid, "accountname", acc); + Uplink::Send(Me, "ADDLINE", xtype, mask, addedby, Anope::CurTime, duration, reason); +} - SASLUser su; - su.uid = uid; - su.acc = acc; - su.created = Anope::CurTime; +void inspircd20::Proto::SendDelLine(const Anope::string &xtype, const Anope::string &mask) +{ + Uplink::Send(Me, "DELLINE", xtype, mask); +} - for (std::list<SASLUser>::iterator it = saslusers.begin(); it != saslusers.end();) - { - SASLUser &u = *it; +inspircd20::Proto::Proto(Module *creator) : ts6::Proto(creator, "InspIRCd 2.0") +{ + DefaultPseudoclientModes = "+I"; + CanSVSNick = true; + CanSVSJoin = true; + CanSetVHost = true; + CanSetVIdent = true; + CanSQLine = true; + CanSZLine = true; + CanSVSHold = true; + CanCertFP = true; + RequiresID = true; + MaxModes = 20; +} - if (u.created + 30 < Anope::CurTime || u.uid == uid) - it = saslusers.erase(it); - else - ++it; - } +void inspircd20::Proto::Handshake() +{ + Uplink::Send("CAPAB START 1202"); + Uplink::Send("CAPAB CAPABILITIES :PROTOCOL=1202"); + Uplink::Send("CAPAB END"); + IRCD->Send<messages::MessageServer>(Me); +} - saslusers.push_back(su); +void inspircd20::Proto::SendNumeric(int numeric, User *dest, IRCMessage &message) +{ + std::vector<Anope::string> params = message.GetParameters(); + if (params.empty()) + return; + + /* First parameter is the UID, change it to nick because it is pushed */ + params[0] = dest->nick; + + IRCMessage m(message.GetSource(), message.GetCommand()); + for (const Anope::string &s : params) + m.Push(s); + + Uplink::Send("PUSH", dest->GetUID(), Format(m)); +} + +void inspircd20::Proto::SendBOB() +{ + Uplink::Send(Me, "BURST", Anope::CurTime); + Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); + Uplink::Send(Me, "VERSION", Anope::Format("Anope-{0} {1} {2} - {3} - Built: {4} - Flags: {5}", + Anope::Version(), Me->GetName(), IRCD->GetProtocolName(), enc ? enc->name : "(none)", Anope::VersionBuildTime(), Anope::VersionFlags())); +} + +void inspircd20::Proto::SendEOB() +{ + Uplink::Send(Me, "ENDBURST"); } bool inspircd20::Proto::IsExtbanValid(const Anope::string &mask) @@ -1162,8 +1126,9 @@ void inspircd20::Save::Run(MessageSource &source, const std::vector<Anope::strin return; } - IRCD->SendKill(Me, targ->nick, "Nick collision"); - IRCD->SendNickChange(targ, targ->nick); + IRCD->Send<messages::Kill>(Me, targ->nick, "Nick collision"); + IRCD->Send<messages::NickChange>(targ, targ->nick, Anope::CurTime); + targ->timestamp = Anope::CurTime; last_collide = Anope::CurTime; } else @@ -1202,7 +1167,7 @@ void inspircd20::SQuit::Run(MessageSource &source, const std::vector<Anope::stri rsquit_server.clear(); if (s && s->IsJuped()) - IRCD->SendServer(s); + IRCD->Send<messages::MessageServer>(s); } else rfc1459::SQuit::Run(source, params); @@ -1318,6 +1283,49 @@ class ProtoInspIRCd20 : public Module inspircd20::Time message_time; inspircd20::UID message_uid; + rfc1459::senders::GlobalNotice sender_global_notice; + rfc1459::senders::GlobalPrivmsg sender_global_privmsg; + rfc1459::senders::Invite sender_invite; + rfc1459::senders::Kick sender_kick; + rfc1459::senders::Kill sender_svskill; + rfc1459::senders::ModeChannel sender_mode_chan; + rfc1459::senders::ModeUser sender_mode_user; + 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; + + hybrid::senders::SVSJoin sender_svsjoin; + hybrid::senders::SVSPart sender_svspart; + + bahamut::senders::SVSNick sender_svsnick; + + inspircd20::senders::Akill sender_akill; + inspircd20::senders::AkillDel sender_akill_del; + inspircd20::senders::MessageChannel sender_channel; + inspircd20::senders::Login sender_login; + inspircd20::senders::Logout sender_logout; + inspircd20::senders::NickIntroduction sender_nickintroduction; + inspircd20::senders::MessageServer sender_server; + inspircd20::senders::SASL sender_sasl; + inspircd20::senders::SASLMechanisms sender_sasl_mechs; + inspircd20::senders::SQLine sender_sqline; + inspircd20::senders::SQLineDel sender_sqline_del; + inspircd20::senders::SQuit sender_squit; + inspircd20::senders::SZLine sender_szline; + inspircd20::senders::SZLineDel sender_szline_del; + inspircd20::senders::SVSHold sender_svshold; + inspircd20::senders::SVSHoldDel sender_svsholddel; + inspircd20::senders::SVSLogin sender_svslogin; + inspircd20::senders::SWhois sender_swhois; + inspircd20::senders::Topic sender_topic; + inspircd20::senders::VhostDel sender_vhost_del; + inspircd20::senders::VhostSet sender_vhost_set; + inspircd20::senders::Wallops sender_wallops; + bool use_server_side_topiclock, use_server_side_mlock; void SendChannelMetadata(Channel *c, const Anope::string &metadataname, const Anope::string &value) @@ -1336,6 +1344,7 @@ class ProtoInspIRCd20 : public Module , ircd_proto(this) , ssl(this, "ssl") + , message_away(this) , message_error(this) , message_invite(this) @@ -1373,7 +1382,53 @@ class ProtoInspIRCd20 : public Module , message_squit(this) , message_time(this) , message_uid(this) + + , sender_akill(this, &ircd_proto) + , sender_akill_del(this, &ircd_proto) + , sender_channel(this) + , sender_global_notice(this) + , sender_global_privmsg(this) + , sender_invite(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_notice(this) + , sender_part(this) + , sender_ping(this) + , sender_pong(this) + , sender_privmsg(this) + , sender_quit(this) + , sender_server(this) + , sender_sasl(this) + , sender_sasl_mechs(this) + , sender_sqline(this, &ircd_proto) + , sender_sqline_del(this, &ircd_proto) + , sender_squit(this) + , sender_szline(this, &ircd_proto) + , sender_szline_del(this, &ircd_proto) + , sender_svshold(this) + , sender_svsholddel(this) + , sender_svslogin(this) + , sender_svsjoin(this) + , sender_svsnick(this) + , sender_svspart(this) + , sender_swhois(this) + , sender_topic(this) + , sender_vhost_del(this, &ircd_proto) + , sender_vhost_set(this, &ircd_proto) + , sender_wallops(this) + { + IRCD = &ircd_proto; + } + + ~ProtoInspIRCd20() { + IRCD = nullptr; } void OnReload(Configuration::Conf *conf) override diff --git a/modules/protocol/ngircd.cpp b/modules/protocol/ngircd.cpp index 1818c1021..7712aec8f 100644 --- a/modules/protocol/ngircd.cpp +++ b/modules/protocol/ngircd.cpp @@ -24,23 +24,7 @@ #include "modules/protocol/rfc1459.h" #include "modules/protocol/ngircd.h" -void ngircd::Proto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) -{ - IRCDProto::SendSVSKill(source, user, buf); - user->KillInternal(source, buf); -} - -ngircd::Proto::Proto(Module *creator) : IRCDProto(creator, "ngIRCd") -{ - DefaultPseudoclientModes = "+oi"; - CanCertFP = true; - CanSVSNick = true; - CanSetVHost = true; - CanSetVIdent = true; - MaxModes = 5; -} - -void ngircd::Proto::SendAkill(User *u, XLine *x) +void ngircd::senders::Akill::Send(User* u, XLine* x) { // Calculate the time left before this would expire, capping it at 2 days time_t timeleft = x->GetExpires() - Anope::CurTime; @@ -49,100 +33,47 @@ void ngircd::Proto::SendAkill(User *u, XLine *x) Uplink::Send(Me, "GLINE", x->GetMask(), timeleft, x->GetReason() + " (" + x->GetBy() + ")"); } -void ngircd::Proto::SendAkillDel(XLine *x) +void ngircd::senders::AkillDel::Send(XLine* x) { Uplink::Send(Me, "GLINE", x->GetMask()); } -void ngircd::Proto::SendChannel(Channel *c) +void ngircd::senders::MessageChannel::Send(Channel* c) { Uplink::Send(Me, "CHANINFO", c->name, "+" + c->GetModes(true, true)); } -// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator -void ngircd::Proto::SendClientIntroduction(User *u) +void ngircd::senders::Login::Send(User *u, NickServ::Nick *na) { - Anope::string modes = "+" + u->GetModes(); - Uplink::Send(Me, "NICK", u->nick, 1, u->GetIdent(), u->host, 1, modes, u->realname); + Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay()); } -void ngircd::Proto::SendConnect() +void ngircd::senders::Logout::Send(User *u) { - Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "0210-IRC+", "Anope|" + Anope::VersionShort(), "CLHMSo P"); - /* Make myself known to myself in the serverlist */ - SendServer(Me); - /* finish the enhanced server handshake and register the connection */ - Uplink::Send("376", "*", "End of MOTD command"); + Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", ""); } -void ngircd::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when) +void ngircd::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts) { Uplink::Send(Me, "SVSNICK", u->nick, newnick); } -void ngircd::Proto::SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "NOTICE", "$" + dest->GetName(), msg); -} - -void ngircd::Proto::SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) -{ - Uplink::Send(bi, "PRIVMSG", "$" + dest->GetName(), msg); -} - -void ngircd::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf) -{ - Uplink::Send(source, "WALLOPS", buf); -} - -void ngircd::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status) -{ - Uplink::Send(user, "JOIN", 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(); - - 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); - - if (uc != NULL) - uc->status = cs; - } -} - -void ngircd::Proto::SendLogin(User *u, NickServ::Nick *na) -{ - Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", na->GetAccount()->GetDisplay()); -} - -void ngircd::Proto::SendLogout(User *u) -{ - Uplink::Send(Me, "METADATA", u->GetUID(), "accountname", ""); -} - -/* SERVER name hop descript */ -void ngircd::Proto::SendServer(Server *server) +// Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator +void ngircd::senders::NickIntroduction::Send(User *user) { - Uplink::Send("SERVER", server->GetName(), server->GetHops(), server->GetDescription()); + Anope::string modes = "+" + user->GetModes(); + Uplink::Send(Me, "NICK", user->nick, 1, user->GetIdent(), user->host, 1, modes, user->realname); } -void ngircd::Proto::SendTopic(const MessageSource &source, Channel *c) +void ngircd::senders::VhostDel::Send(User* u) { - Uplink::Send(source, "TOPIC", c->name, c->topic); + IRCD->Send<messages::VhostSet>(u, u->GetIdent(), ""); } -void ngircd::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) +void ngircd::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost) { - if (!vIdent.empty()) - Uplink::Send(Me, "METADATA", u->nick, "user", vIdent); + if (!vident.empty()) + Uplink::Send(Me, "METADATA", u->nick, "user", vident); Uplink::Send(Me, "METADATA", u->nick, "cloakhost", vhost); if (!u->HasMode("CLOAK")) @@ -152,9 +83,23 @@ void ngircd::Proto::SendVhost(User *u, const Anope::string &vIdent, const Anope: } } -void ngircd::Proto::SendVhostDel(User *u) +ngircd::Proto::Proto(Module *creator) : IRCDProto(creator, "ngIRCd") { - this->SendVhost(u, u->GetIdent(), ""); + DefaultPseudoclientModes = "+oi"; + CanCertFP = true; + CanSVSNick = true; + CanSetVHost = true; + CanSetVIdent = true; + MaxModes = 5; +} + +void ngircd::Proto::Handshake() +{ + Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "0210-IRC+", "Anope|" + Anope::VersionShort(), "CLHMSo P"); + /* Make myself known to myself in the serverlist */ + IRCD->Send<messages::MessageServer>(Me); + /* finish the enhanced server handshake and register the connection */ + Uplink::Send("376", "*", "End of MOTD command"); } Anope::string ngircd::Proto::Format(IRCMessage &message) @@ -508,7 +453,7 @@ void ngircd::ServerMessage::Run(MessageSource &source, const std::vector<Anope:: * when receiving a new server and then finish sync once we * get a pong back from that server. */ - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send<messages::Ping>(Me->GetName(), params[0]); } class ProtongIRCd : public Module @@ -546,6 +491,36 @@ class ProtongIRCd : public Module ngircd::Pong message_pong; ngircd::ServerMessage message_server; + /* Core message senders */ + rfc1459::senders::GlobalNotice sender_global_notice; + rfc1459::senders::GlobalPrivmsg sender_global_privmsg; + rfc1459::senders::Invite sender_invite; + rfc1459::senders::Join sender_join; + rfc1459::senders::Kick sender_kick; + rfc1459::senders::Kill sender_svskill; + rfc1459::senders::ModeChannel sender_mode_chan; + rfc1459::senders::ModeUser sender_mode_user; + 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; + rfc1459::senders::Topic sender_topic; + rfc1459::senders::Wallops sender_wallops; + + ngircd::senders::Akill sender_akill; + ngircd::senders::AkillDel sender_akill_del; + ngircd::senders::MessageChannel sender_channel; + ngircd::senders::Login sender_login; + ngircd::senders::Logout sender_logout; + ngircd::senders::SVSNick sender_svsnick; + ngircd::senders::VhostDel sender_vhost_del; + ngircd::senders::VhostSet sender_vhost_set; + public: ProtongIRCd(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , EventHook<Event::UserNickChange>(this) @@ -578,10 +553,43 @@ class ProtongIRCd : public Module , message_pong(this) , message_server(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_svskill(this) + , sender_login(this) + , sender_logout(this) + , sender_mode_chan(this) + , sender_mode_user(this) + , sender_nickchange(this) + , sender_notice(this) + , sender_part(this) + , sender_ping(this) + , sender_pong(this) + , sender_privmsg(this) + , sender_quit(this) + , sender_server(this) + , sender_squit(this) + , sender_svsnick(this) + , sender_topic(this) + , sender_vhost_del(this) + , sender_vhost_set(this) + , sender_wallops(this) + { Servers::Capab.insert("QS"); + IRCD = &ircd_proto; + } + + ~ProtongIRCd() + { + IRCD = nullptr; } void OnUserNickChange(User *u, const Anope::string &) override diff --git a/modules/protocol/plexus.cpp b/modules/protocol/plexus.cpp index eb1fe48b5..68c23f18e 100644 --- a/modules/protocol/plexus.cpp +++ b/modules/protocol/plexus.cpp @@ -17,78 +17,83 @@ * along with this program; if not, see see <http://www.gnu.org/licenses/>. */ -/* Dependencies: anope_protocol.hybrid */ +/* Dependencies: anope_protocol.ratbox */ #include "module.h" #include "modules/protocol/plexus.h" #include "modules/protocol/hybrid.h" +#include "modules/protocol/ratbox.h" static Anope::string UplinkSID; -plexus::Proto::Proto(Module *creator) : IRCDProto(creator, "hybrid-7.2.3+plexus-3.0.1") - , hybrid("hybrid") +void plexus::senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes) { - DefaultPseudoclientModes = "+oiU"; - CanSVSNick = true; - CanSVSJoin = true; - CanSetVHost = true; - CanSetVIdent = true; - CanSNLine = true; - CanSQLine = true; - CanSQLineChannel = true; - CanSVSHold = true; - CanCertFP = true; - RequiresID = true; - MaxModes = 4; + IRCMessage message(source, "ENCAP", "*", "SVSMODE", user->GetUID(), user->timestamp); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); } -void plexus::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf) +void plexus::senders::NickIntroduction::Send(User *user) { - Uplink::Send(source, "OPERWALL", buf); + Anope::string modes = "+" + user->GetModes(); + Uplink::Send(Me, "UID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, "255.255.255.255", user->GetUID(), 0, user->host, user->realname); } -void plexus::Proto::SendJoin(User *user, Channel *c, const ChannelStatus *status) +void plexus::senders::NOOP::Send(Server* server, bool mode) { - Uplink::Send(Me, "SJOIN", c->creation_time, c->name, "+" + c->GetModes(true, true), user->GetUID()); - 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(); - - 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); - - if (uc != NULL) - uc->status = cs; - } + Uplink::Send("ENCAP", server->GetName(), "SVSNOOP", (mode ? "+" : "-")); } -void plexus::Proto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when) +void plexus::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) { - Uplink::Send(Me, "ENCAP", u->server->GetName(), "SVSNICK", u->GetUID(), u->timestamp, newnick, when); + Uplink::Send(source, "ENCAP", "*", "TOPIC", channel->name, topic_setter, topic_ts, topic); } -void plexus::Proto::SendVhost(User *u, const Anope::string &ident, const Anope::string &host) +void plexus::senders::SVSJoin::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& key) { - if (!ident.empty()) - Uplink::Send(Me, "ENCAP", "*", "CHGIDENT", u->GetUID(), ident); - Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), host); - u->SetMode(Config->GetClient("HostServ"), "CLOAK"); + Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSJOIN", user->GetUID(), chan); +} + +void plexus::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts) +{ + Uplink::Send(Me, "ENCAP", u->server->GetName(), "SVSNICK", u->GetUID(), u->timestamp, newnick, ts); +} + +void plexus::senders::SVSPart::Send(const MessageSource& source, User* user, const Anope::string& chan, const Anope::string& reason) +{ + Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSPART", user->GetUID(), chan); } -void plexus::Proto::SendVhostDel(User *u) +void plexus::senders::VhostDel::Send(User* u) { u->RemoveMode(Config->GetClient("HostServ"), "CLOAK"); } -void plexus::Proto::SendConnect() +void plexus::senders::VhostSet::Send(User* u, const Anope::string& vident, const Anope::string& vhost) +{ + if (!vident.empty()) + Uplink::Send(Me, "ENCAP", "*", "CHGIDENT", u->GetUID(), vident); + Uplink::Send(Me, "ENCAP", "*", "CHGHOST", u->GetUID(), vhost); + u->SetMode(Config->GetClient("HostServ"), "CLOAK"); +} + +plexus::Proto::Proto(Module *creator) : ts6::Proto(creator, "Plexus 4") +{ + DefaultPseudoclientModes = "+oiU"; + CanSVSNick = true; + CanSVSJoin = true; + CanSetVHost = true; + CanSetVIdent = true; + CanSNLine = true; + CanSQLine = true; + CanSQLineChannel = true; + CanSVSHold = true; + CanCertFP = true; + RequiresID = true; + MaxModes = 4; +} + +void plexus::Proto::Handshake() { Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID()); @@ -115,7 +120,7 @@ void plexus::Proto::SendConnect() Uplink::Send("CAPAB", "QS EX CHW IE EOB KLN UNKLN GLN HUB KNOCK TBURST PARA ENCAP SVS"); /* Make myself known to myself in the serverlist */ - SendServer(Me); + Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription()); /* * SVINFO @@ -128,42 +133,6 @@ void plexus::Proto::SendConnect() Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime); } -void plexus::Proto::SendClientIntroduction(User *u) -{ - Anope::string modes = "+" + u->GetModes(); - Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, "255.255.255.255", u->GetUID(), 0, u->host, u->realname); -} - -void plexus::Proto::SendMode(const MessageSource &source, User *u, const Anope::string &buf) -{ - Uplink::Send(source, "ENCAP", "*", "SVSMODE", u->GetUID(), u->timestamp, buf); -} - -void plexus::Proto::SendLogin(User *u, NickServ::Nick *na) -{ - Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay()); -} - -void plexus::Proto::SendLogout(User *u) -{ - Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), ""); -} - -void plexus::Proto::SendTopic(const MessageSource &source, Channel *c) -{ - Uplink::Send(source, "ENCAP", "*", "TOPIC", c->name, c->topic_setter, c->topic_ts, c->topic); -} - -void plexus::Proto::SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) -{ - Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSJOIN", user->GetUID(), chan); -} - -void plexus::Proto::SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) -{ - Uplink::Send(source, "ENCAP", user->server->GetName(), "SVSPART", user->GetUID(), chan); -} - void plexus::Encap::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { /* @@ -269,8 +238,6 @@ void plexus::UID::Run(MessageSource &source, const std::vector<Anope::string> &p class ProtoPlexus : public Module { - Module *m_hybrid; - plexus::Proto ircd_proto; /* Core message handlers */ @@ -308,6 +275,46 @@ class ProtoPlexus : public Module hybrid::TMode message_tmode; plexus::UID message_uid; + /* Core message senders */ + rfc1459::senders::Invite sender_invite; + rfc1459::senders::Kick sender_kick; + rfc1459::senders::Kill sender_svskill; + 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; + + hybrid::senders::Akill sender_akill; + hybrid::senders::AkillDel sender_akill_del; + hybrid::senders::MessageChannel sender_channel; + hybrid::senders::GlobalNotice sender_global_notice; + hybrid::senders::GlobalPrivmsg sender_global_privmsg; + hybrid::senders::Join sender_join; + hybrid::senders::MessageServer sender_server; + hybrid::senders::SQLine sender_sqline; + hybrid::senders::SQLineDel sender_sqline_del; + hybrid::senders::SVSHold sender_svshold; + hybrid::senders::SVSHoldDel sender_svsholddel; + + ratbox::senders::Login sender_login; + ratbox::senders::Logout sender_logout; + ratbox::senders::Wallops sender_wallops; + + plexus::senders::ModeUser sender_mode_user; + plexus::senders::NickIntroduction sender_nickintroduction; + plexus::senders::NOOP sender_noop; + plexus::senders::SVSJoin sender_svsjoin; + plexus::senders::SVSNick sender_svsnick; + plexus::senders::SVSPart sender_svspart; + plexus::senders::Topic sender_topic; + plexus::senders::VhostDel sender_vhost_del; + plexus::senders::VhostSet sender_vhost_set; + public: ProtoPlexus(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , ircd_proto(this) @@ -343,7 +350,49 @@ class ProtoPlexus : public Module , message_tburst(this) , message_tmode(this) , message_uid(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_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_topic(this) + , sender_vhost_del(this) + , sender_vhost_set(this) + , sender_wallops(this) + { + IRCD = &ircd_proto; + } + + ~ProtoPlexus() { + IRCD = nullptr; } }; diff --git a/modules/protocol/ratbox.cpp b/modules/protocol/ratbox.cpp index 592002578..0a20093e7 100644 --- a/modules/protocol/ratbox.cpp +++ b/modules/protocol/ratbox.cpp @@ -25,6 +25,72 @@ static Anope::string UplinkSID; +void ratbox::senders::NickIntroduction::Send(User *user) +{ + Anope::string modes = "+" + user->GetModes(); + Uplink::Send(Me, "UID", user->nick, 1, user->timestamp, modes, user->GetIdent(), user->host, 0, user->GetUID(), user->realname); +} + +void ratbox::senders::Login::Send(User *u, NickServ::Nick *na) +{ + if (na->GetAccount()->IsUnconfirmed()) + return; + + Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay()); +} + +void ratbox::senders::Logout::Send(User *u) +{ + Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID()); +} + +void ratbox::senders::SQLine::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; + +#warning "find introduced" +// Uplink::Send(FindIntroduced(), "ENCAP", "*", "RESV", timeleft, x->GetMask(), 0, x->GetReason()); +} + +void ratbox::senders::SQLineDel::Send(XLine* x) +{ + Uplink::Send(Config->GetClient("OperServ"), "ENCAP", "*", "UNRESV", x->GetMask()); +} + +void ratbox::senders::SVSNick::Send(User* u, const Anope::string& newnick, time_t ts) +{ + Uplink::Send(Me, "ENCAP", u->server->GetName(), "RSFNC", u->GetUID(), + newnick, ts, u->timestamp); +} + +void ratbox::senders::Topic::Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) +{ + ServiceBot *bi = source.GetBot(); + bool needjoin = channel->FindUser(bi) == NULL; + + if (needjoin) + { + ChannelStatus status; + + status.AddMode('o'); + bi->Join(channel, &status); + } + + rfc1459::senders::Topic::Send(source, channel, topic, topic_ts, topic_setter); + + if (needjoin) + bi->Part(channel); +} + +void ratbox::senders::Wallops::Send(const MessageSource &source, const Anope::string &msg) +{ + Uplink::Send(source, "OPERWALL", msg); +} + ServiceBot *ratbox::Proto::FindIntroduced() { ServiceBot *bi = Config->GetClient("OperServ"); @@ -45,10 +111,11 @@ ServiceBot *ratbox::Proto::FindIntroduced() return NULL; } -ratbox::Proto::Proto(Module *creator) : IRCDProto(creator, "Ratbox 3.0+") - , hybrid("hybrid") +ratbox::Proto::Proto(Module *creator) : ts6::Proto(creator, "Ratbox 3.0+") + , hybrid(creator) { DefaultPseudoclientModes = "+oiS"; + CanSVSNick = true; CanSNLine = true; CanSQLine = true; CanSQLineChannel = true; @@ -57,12 +124,7 @@ ratbox::Proto::Proto(Module *creator) : IRCDProto(creator, "Ratbox 3.0+") MaxModes = 4; } -void ratbox::Proto::SendGlobops(const MessageSource &source, const Anope::string &buf) -{ - Uplink::Send(source, "OPERWALL", buf); -} - -void ratbox::Proto::SendConnect() +void ratbox::Proto::Handshake() { Uplink::Send("PASS", Config->Uplinks[Anope::CurrentUplink].password, "TS", 6, Me->GetSID()); @@ -79,7 +141,7 @@ void ratbox::Proto::SendConnect() Uplink::Send("CAPAB", "QS EX CHW IE GLN TB ENCAP"); /* Make myself known to myself in the serverlist */ - SendServer(Me); + Uplink::Send("SERVER", Me->GetName(), Me->GetHops() + 1, Me->GetDescription()); /* * SVINFO @@ -92,60 +154,6 @@ void ratbox::Proto::SendConnect() Uplink::Send("SVINFO", 6, 6, 0, Anope::CurTime); } -void ratbox::Proto::SendClientIntroduction(User *u) -{ - Anope::string modes = "+" + u->GetModes(); - Uplink::Send(Me, "UID", u->nick, 1, u->timestamp, modes, u->GetIdent(), u->host, 0, u->GetUID(), u->realname); -} - -void ratbox::Proto::SendLogin(User *u, NickServ::Nick *na) -{ - if (na->GetAccount()->IsUnconfirmed()) - return; - - Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID(), na->GetAccount()->GetDisplay()); -} - -void ratbox::Proto::SendLogout(User *u) -{ - Uplink::Send(Me, "ENCAP", "*", "SU", u->GetUID()); -} - -void ratbox::Proto::SendTopic(const MessageSource &source, Channel *c) -{ - ServiceBot *bi = source.GetBot(); - bool needjoin = c->FindUser(bi) == NULL; - - if (needjoin) - { - ChannelStatus status; - - status.AddMode('o'); - bi->Join(c, &status); - } - - IRCDProto::SendTopic(source, c); - - if (needjoin) - bi->Part(c); -} - -void ratbox::Proto::SendSQLine(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; - - Uplink::Send(FindIntroduced(), "ENCAP", "*", "RESV", timeleft, x->GetMask(), 0, x->GetReason()); -} - -void ratbox::Proto::SendSQLineDel(XLine *x) -{ - Uplink::Send(Config->GetClient("OperServ"), "ENCAP", "*", "UNRESV", x->GetMask()); -} - // Debug: Received: :00BAAAAAB ENCAP * LOGIN Adam void ratbox::Encap::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { @@ -197,7 +205,7 @@ void ratbox::ServerMessage::Run(MessageSource &source, const std::vector<Anope:: if (params[1] != "1") return; new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], 1, params[2], UplinkSID); - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send<messages::Ping>(Me->GetName(), params[0]); } /* @@ -279,6 +287,40 @@ class ProtoRatbox : public Module hybrid::TMode message_tmode; ratbox::UID message_uid; + /* Core message senders */ + rfc1459::senders::Invite sender_invite; + rfc1459::senders::Kick sender_kick; + rfc1459::senders::Kill sender_svskill; + 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; + + hybrid::senders::Akill sender_akill; + hybrid::senders::AkillDel sender_akill_del; + hybrid::senders::MessageChannel sender_channel; + hybrid::senders::GlobalNotice sender_global_notice; + hybrid::senders::GlobalPrivmsg sender_global_privmsg; + hybrid::senders::Join sender_join; + hybrid::senders::ModeUser sender_mode_user; + hybrid::senders::MessageServer sender_server; + hybrid::senders::SGLine sender_sgline; + hybrid::senders::SGLineDel sender_sgline_del; + + ratbox::senders::Login sender_login; + ratbox::senders::Logout sender_logout; + ratbox::senders::NickIntroduction sender_nickintroduction; + ratbox::senders::SQLine sender_sqline; + ratbox::senders::SQLineDel sender_sqline_del; + ratbox::senders::SVSNick sender_svsnick; + ratbox::senders::Topic sender_topic; + ratbox::senders::Wallops sender_wallops; + public: ProtoRatbox(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL | VENDOR) , ircd_proto(this) @@ -314,7 +356,44 @@ class ProtoRatbox : public Module , message_tb(this) , message_tmode(this) , message_uid(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_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_squit(this) + , sender_svsnick(this) + , sender_topic(this) + , sender_wallops(this) + { + IRCD = &ircd_proto; + } + + ~ProtoRatbox() { + IRCD = nullptr; } }; diff --git a/modules/protocol/rfc1459.cpp b/modules/protocol/rfc1459.cpp index 1314f7d39..1405e121e 100644 --- a/modules/protocol/rfc1459.cpp +++ b/modules/protocol/rfc1459.cpp @@ -23,6 +23,146 @@ using namespace rfc1459; +void senders::GlobalNotice::Send(const MessageSource &source, Server *dest, const Anope::string &msg) +{ + Uplink::Send(source, "NOTICE", "$" + dest->GetName(), msg); +} + +void senders::GlobalPrivmsg::Send(const MessageSource& source, Server* dest, const Anope::string& msg) +{ + Uplink::Send(source, "PRIVMSG", "$" + dest->GetName(), msg); +} + +void senders::Invite::Send(const MessageSource &source, Channel *chan, User *user) +{ + Uplink::Send(source, "INVITE", user->GetUID(), chan->name); +} + +void senders::Join::Send(User* user, Channel* c, const ChannelStatus* status) +{ + Uplink::Send(user, "JOIN", 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(); + + 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); + + if (uc != NULL) + uc->status = cs; + } +} + +void senders::Kick::Send(const MessageSource &source, Channel *chan, User *user, const Anope::string &reason) +{ + if (!reason.empty()) + Uplink::Send(source, "KICK", chan->name, user->GetUID(), reason); + else + Uplink::Send(source, "KICK", chan->name, user->GetUID()); +} + +void senders::Kill::Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) +{ + Uplink::Send(source, "KILL", target, reason); +} + +void senders::Kill::Send(const MessageSource &source, User *user, const Anope::string &reason) +{ + Uplink::Send(source, "KILL", user->GetUID(), reason); + user->KillInternal(source, reason); +} + +void senders::ModeChannel::Send(const MessageSource &source, Channel *channel, const Anope::string &modes) +{ + IRCMessage message(source, "MODE", channel->name); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); +} + +void senders::ModeUser::Send(const MessageSource &source, User *user, const Anope::string &modes) +{ + IRCMessage message(source, "MODE", user->GetUID()); + message.TokenizeAndPush(modes); + Uplink::SendMessage(message); +} + +void senders::NickChange::Send(User *u, const Anope::string &newnick, time_t ts) +{ + /* this actually isn't rfc1459 which says NICK <nickname> <hopcount> */ + Uplink::Send(u, "NICK", newnick, ts); +} + +void senders::Notice::Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) +{ + Uplink::Send(source, "NOTICE", dest, msg); +} + +void senders::Part::Send(User *u, Channel *chan, const Anope::string &reason) +{ + if (!reason.empty()) + Uplink::Send(u, "PART", chan->name, reason); + else + Uplink::Send(u, "PART", chan->name); +} + +void senders::Ping::Send(const Anope::string &servname, const Anope::string &who) +{ + if (servname.empty()) + Uplink::Send(Me, "PING", who); + else + Uplink::Send(Me, "PING", servname, who); +} + +void senders::Pong::Send(const Anope::string &servname, const Anope::string &who) +{ + if (servname.empty()) + Uplink::Send(Me, "PONG", who); + else + Uplink::Send(Me, "PONG", servname, who); +} + +void senders::Privmsg::Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) +{ + Uplink::Send(source, "PRIVMSG", dest, msg); +} + +void senders::Quit::Send(User *user, const Anope::string &reason) +{ + if (!reason.empty()) + Uplink::Send(user, "QUIT", reason); + else + Uplink::Send(user, "QUIT"); +} + +void senders::MessageServer::Send(Server* server) +{ + Uplink::Send("SERVER", server->GetName(), server->GetHops() + 1, server->GetDescription()); +} + +void senders::SQuit::Send(Server *s, const Anope::string &message) +{ + Uplink::Send("SQUIT", s->GetSID(), message); +} + +void 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); +} + +void senders::Wallops::Send(const MessageSource &source, const Anope::string &msg) +{ + Uplink::Send(source, "WALLOPS", msg); +} + void Away::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { const Anope::string &msg = !params.empty() ? params[0] : ""; @@ -300,7 +440,7 @@ void Part::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) void Ping::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) { - IRCD->SendPong(params.size() > 1 ? params[1] : Me->GetSID(), params[0]); + IRCD->Send<messages::Pong>(params.size() > 1 ? params[1] : Me->GetSID(), params[0]); } void Privmsg::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) diff --git a/modules/protocol/ts6.cpp b/modules/protocol/ts6.cpp new file mode 100644 index 000000000..888eebcd7 --- /dev/null +++ b/modules/protocol/ts6.cpp @@ -0,0 +1,71 @@ +/* + * Anope IRC Services + * + * Copyright (C) 2016 Anope Team <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. + * + * 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. + * + * 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/>. + */ + +#include "module.h" +#include "modules/protocol/ts6.h" + +static inline char nextID(int pos, Anope::string &buf) +{ + char &c = buf[pos]; + if (c == 'Z') + c = '0'; + else if (c != '9') + ++c; + else if (pos) + c = 'A'; + else + c = '0'; + return c; +} + +Anope::string ts6::Proto::UID_Retrieve() +{ + if (!IRCD || !IRCD->RequiresID) + return ""; + + static Anope::string current_uid = "AAAAAA"; + int current_len = current_uid.length() - 1; + + do + { + while (current_len >= 0 && nextID(current_len--, current_uid) == 'A'); + } + while (User::Find(Me->GetSID() + current_uid) != nullptr); + + return Me->GetSID() + current_uid; +} + +Anope::string ts6::Proto::SID_Retrieve() +{ + if (!IRCD || !IRCD->RequiresID) + return ""; + + static Anope::string current_sid = Config->GetBlock("serverinfo")->Get<Anope::string>("id"); + if (current_sid.empty()) + current_sid = "00A"; + + do + { + int current_len = current_sid.length() - 1; + while (current_len >= 0 && nextID(current_len--, current_sid) == 'A'); + } + while (Server::Find(current_sid) != nullptr); + + return current_sid; +} 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 <http://www.gnu.org/licenses/>. */ -/* 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<messages::SZLine>(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<messages::SZLineDel>(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::vector<Anope:: new Server(source.GetServer(), params[0], hops, params[2]); } - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send<messages::Ping>(Me->GetName(), params[0]); } void unreal::SID::Run(MessageSource &source, const std::vector<Anope::string> ¶ms) @@ -904,7 +870,7 @@ void unreal::SID::Run(MessageSource &source, const std::vector<Anope::string> &p new Server(source.GetServer(), params[0], hops, params[3], params[2]); - IRCD->SendPing(Me->GetName(), params[0]); + IRCD->Send<messages::Ping>(Me->GetName(), params[0]); } void unreal::SJoin::Run(MessageSource &source, const std::vector<Anope::string> ¶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 diff --git a/modules/sasl.cpp b/modules/sasl.cpp index 9feb3ffa6..d8cd83dcf 100644 --- a/modules/sasl.cpp +++ b/modules/sasl.cpp @@ -231,7 +231,7 @@ class SASLService : public SASL::Service, public Timer msg.type = mtype; msg.data = data; - IRCD->SendSASLMessage(msg); + IRCD->Send<messages::SASL>(msg); } void Succeed(Session *session, NickServ::Account *nc) override @@ -246,8 +246,8 @@ class SASLService : public SASL::Service, public Timer } else { - HostServ::VHost *vhost = HostServ::FindVHost(na->GetAccount()); - IRCD->SendSVSLogin(session->uid, nc->GetDisplay(), vhost ? vhost->GetIdent() : "", vhost ? vhost->GetHost() : ""); + HostServ::VHost *vhost = HostServ::FindVHost(nc); + IRCD->Send<messages::SVSLogin>(session->uid, nc->GetDisplay(), vhost ? vhost->GetIdent() : "", vhost ? vhost->GetHost() : ""); } this->SendMessage(session, "D", "S"); } @@ -348,7 +348,7 @@ class ModuleSASL : public Module // If we are connected to the network then broadcast the mechlist. if (Me && Me->IsSynced()) - IRCD->SendSASLMechanisms(mechs); + IRCD->Send<messages::SASLMechanisms>(mechs); } public: @@ -386,7 +386,7 @@ class ModuleSASL : public Module void OnPreUplinkSync(Server *) override { // We have not yet sent a mechanism list so always do it here. - IRCD->SendSASLMechanisms(mechs); + IRCD->Send<messages::SASLMechanisms>(mechs); } }; |
