diff options
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); } }; |
