diff options
56 files changed, 3765 insertions, 1819 deletions
diff --git a/data/anope.example.conf b/data/anope.example.conf index 408120c37..89c63ebfd 100644 --- a/data/anope.example.conf +++ b/data/anope.example.conf @@ -643,7 +643,7 @@ log * Target(s) to log to, which may be one of the following: * - a channel name * - a filename - * - globops + * - wallops */ target = "services.log" @@ -721,11 +721,11 @@ log } /* - * A log block to globops some useful things. + * A log block to wallop some useful things. */ log { - target = "globops" + target = "wallops" admin = "global/* operserv/chankill operserv/mode operserv/kick operserv/akill operserv/s*line operserv/noop operserv/jupe operserv/set operserv/svsnick operserv/svsjoin operserv/svspart */drop" servers = "squit" users = "oper" @@ -831,11 +831,6 @@ opertype /* * Modes to be set on users when they identify to accounts linked to this opertype. - * - * This can be used to automatically oper users who identify for services operator accounts, and is - * useful for setting modes such as Plexus's user mode +N. - * - * Note that some IRCds, such as InspIRCd, do not allow directly setting +o, and this will not work. */ #modes = "+o" } diff --git a/data/hybrid.example.conf b/data/hybrid.example.conf index 6e9f4da6f..6ec0f5da6 100644 --- a/data/hybrid.example.conf +++ b/data/hybrid.example.conf @@ -121,7 +121,7 @@ channelmode channelmode { name = "HALFOP" - characater = "h" + character = "h" status = "%" level = 2 } diff --git a/data/plexus.example.conf b/data/plexus.example.conf index 9d1204828..9bf095e97 100644 --- a/data/plexus.example.conf +++ b/data/plexus.example.conf @@ -161,7 +161,7 @@ channelmode channelmode { name = "HALFOP" - characater = "h" + character = "h" status = "%" level = 2 } diff --git a/include/channels.h b/include/channels.h index d3161b7ae..31fa582c4 100644 --- a/include/channels.h +++ b/include/channels.h @@ -70,7 +70,7 @@ class CoreExport Channel : public Base, public Extensible Anope::string topic; /* Who set the topic */ Anope::string topic_setter; - /* The timestamp associated with the topic. Not necessarually anywhere close to Anope::CurTime. + /* The timestamp associated with the topic. Not necessarily anywhere close to Anope::CurTime. * This is the time the topic was *originally set*. When we restore the topic we want to change the TS back * to this, but we can only do this on certain IRCds. */ diff --git a/include/messages.h b/include/messages.h new file mode 100644 index 000000000..3361d5740 --- /dev/null +++ b/include/messages.h @@ -0,0 +1,558 @@ +/* + * 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/>. + */ + +#pragma once + +template<typename T> +class MessageSender : public Service +{ + public: + static constexpr const char *NAME = "messagesender"; + + MessageSender(Module *owner) : Service(owner, NAME, T::NAME) { } +}; + +namespace messages +{ + +class Akill : public MessageSender<Akill> +{ + public: + static constexpr const char *NAME = "akill"; + + using MessageSender::MessageSender; + + /** Sets an akill. This is a recursive function that can be called multiple times + * for the same xline, but for different users, if the xline is not one that can be + * enforced by the IRCd, such as a nick/user/host/realname combination ban. + * @param u The user affected by the akill, if known + * @param x The akill + */ + virtual void Send(User *, XLine *) anope_abstract; +}; + +class AkillDel : public MessageSender<AkillDel> +{ + public: + static constexpr const char *NAME = "akilldel"; + + using MessageSender::MessageSender; + + virtual void Send(XLine *) anope_abstract; +}; + +class MessageChannel : public MessageSender<MessageChannel> +{ + public: + static constexpr const char *NAME = "channel"; + + using MessageSender::MessageSender; + + /** Send a channel creation message to the uplink. + * On most IRCds this is a SJOIN with no nicks + */ + virtual void Send(Channel *) anope_abstract; +}; + +class GlobalNotice : public MessageSender<GlobalNotice> +{ + public: + static constexpr const char *NAME = "globalnotice"; + + using MessageSender::MessageSender; + + virtual void Send(const MessageSource &, Server *dest, const Anope::string &msg) anope_abstract; +}; + +class GlobalPrivmsg : public MessageSender<GlobalPrivmsg> +{ + public: + static constexpr const char *NAME = "globalprivmsg"; + + using MessageSender::MessageSender; + + virtual void Send(const MessageSource &, Server *dest, const Anope::string &msg) anope_abstract; +}; + +class Invite : public MessageSender<Invite> +{ + public: + static constexpr const char *NAME = "invite"; + + using MessageSender::MessageSender; + + virtual void Send(const MessageSource &source, Channel *c, User *u) anope_abstract; +}; + +class Join : public MessageSender<Join> +{ + public: + static constexpr const char *NAME = "join"; + + using MessageSender::MessageSender; + + /** Joins one of our users to a channel. + * @param u The user to join + * @param c The channel to join the user to + * @param status The status to set on the user after joining. This may or may not already internally + * be set on the user. This may include the modes in the join, but will usually place them on the mode + * stacker to be set "soon". + */ + virtual void Send(User *u, Channel *c, const ChannelStatus *status) anope_abstract; +}; + +class Kick : public MessageSender<Kick> +{ + public: + static constexpr const char *NAME = "kick"; + + using MessageSender::MessageSender; + + /** Kick a user from a channel + * @param source Who is doing the kick + * @param channel Channel + * @param user Target of the kick + * @param reason Kick reason + */ + virtual void Send(const MessageSource &source, Channel *channel, User *user, const Anope::string &reason) anope_abstract; +}; + +class Kill : public MessageSender<Kill> +{ + public: + static constexpr const char *NAME = "svskill"; + + using MessageSender::MessageSender; + + virtual void Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) anope_abstract; + + /** Kills a user + * @param source Who is doing the kill + * @param user The target to be killed + * @param reason Kill reason + */ + virtual void Send(const MessageSource &source, User *user, const Anope::string &reason) anope_abstract; +}; + +class Login : public MessageSender<Login> +{ + public: + static constexpr const char *NAME = "login"; + + using MessageSender::MessageSender; + + virtual void Send(User *u, NickServ::Nick *na) anope_abstract; +}; + +class Logout : public MessageSender<Logout> +{ + public: + static constexpr const char *NAME = "logout"; + + using MessageSender::MessageSender; + + virtual void Send(User *u) anope_abstract; +}; + +class ModeChannel : public MessageSender<ModeChannel> +{ + public: + static constexpr const char *NAME = "modechannel"; + + using MessageSender::MessageSender; + + /** Changes the mode on a channel + * @param source Who is changing the mode + * @param channel Channel + * @param modes Modes eg +nt + */ + virtual void Send(const MessageSource &source, Channel *channel, const Anope::string &modes) anope_abstract; +}; + +class ModeUser : public MessageSender<ModeUser> +{ + public: + static constexpr const char *NAME = "modeuser"; + + using MessageSender::MessageSender; + + /** Changes the mode on a user + * @param source Who is changing the mode + * @param user user + * @param modes Modes eg +i + */ + virtual void Send(const MessageSource &source, User *user, const Anope::string &modes) anope_abstract; +}; + +class NickChange : public MessageSender<NickChange> +{ + public: + static constexpr const char *NAME = "nickchange"; + + using MessageSender::MessageSender; + + /** Sends a nick change of one of our clients. + */ + virtual void Send(User *u, const Anope::string &newnick, time_t ts) anope_abstract; +}; + +class NickIntroduction : public MessageSender<NickIntroduction> +{ + public: + static constexpr const char *NAME = "nickintroduction"; + + using MessageSender::MessageSender; + + /** Introduces a client to the rest of the network + * @param user The client to introduce + */ + virtual void Send(User *user) anope_abstract; +}; + +class NOOP : public MessageSender<NOOP> +{ + public: + static constexpr const char *NAME = "noop"; + + using MessageSender::MessageSender; + + /** Sets the server in NOOP mode. If NOOP mode is enabled, no users + * will be able to oper on the server. + * @param s The server + * @param mode Whether to turn NOOP on or off + */ + virtual void Send(Server *s, bool mode) anope_abstract; +}; + +class Notice : public MessageSender<Notice> +{ + public: + static constexpr const char *NAME = "notice"; + + using MessageSender::MessageSender; + + /** Send a notice to a target + * @param source Source of the notice + * @param dest Destination user/channel + * @param msg Message to send + */ + virtual void Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) anope_abstract; +}; + +class Part : public MessageSender<Part> +{ + public: + static constexpr const char *NAME = "part"; + + using MessageSender::MessageSender; + + virtual void Send(User *, Channel *chan, const Anope::string &reason) anope_abstract; +}; + +class Ping : public MessageSender<Ping> +{ + public: + static constexpr const char *NAME = "ping"; + + using MessageSender::MessageSender; + + virtual void Send(const Anope::string &servname, const Anope::string &who) anope_abstract; +}; + +class Pong : public MessageSender<Pong> +{ + public: + static constexpr const char *NAME = "pong"; + + using MessageSender::MessageSender; + + /** + * Send a PONG reply to a received PING. + * servname should be left empty to send a one param reply. + * @param servname Daemon or client that is responding to the PING. + * @param who Origin of the PING and destination of the PONG message. + **/ + virtual void Send(const Anope::string &servname, const Anope::string &who) anope_abstract; +}; + +class Privmsg : public MessageSender<Privmsg> +{ + public: + static constexpr const char *NAME = "privmsg"; + + using MessageSender::MessageSender; + + /** Send a privmsg to a target + * @param source Source of the privmsg + * @param dest Destination user/channel + * @param msg Message to send + */ + virtual void Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) anope_abstract; +}; + +class Quit : public MessageSender<Quit> +{ + public: + static constexpr const char *NAME = "quit"; + + using MessageSender::MessageSender; + + virtual void Send(User *user, const Anope::string &reason) anope_abstract; +}; + +class MessageServer : public MessageSender<MessageServer> +{ + public: + static constexpr const char *NAME = "server"; + + using MessageSender::MessageSender; + + /** Introduces a server to the uplink + */ + virtual void Send(Server *s) anope_abstract; +}; + +class SASL : public MessageSender<SASL> +{ + public: + static constexpr const char *NAME = "sasl"; + + using MessageSender::MessageSender; + + virtual void Send(const ::SASL::Message &) anope_abstract; +}; + +class SASLMechanisms : public MessageSender<SASLMechanisms> +{ + public: + static constexpr const char *NAME = "saslmechanisms"; + + using MessageSender::MessageSender; + + virtual void Send(const std::vector<Anope::string> &mechanisms) anope_abstract; +}; + +// realname ban +class SGLine : public MessageSender<SGLine> +{ + public: + static constexpr const char *NAME = "sgline"; + + using MessageSender::MessageSender; + + virtual void Send(User *, XLine *) anope_abstract; +}; + +class SGLineDel : public MessageSender<SGLineDel> +{ + public: + static constexpr const char *NAME = "sglinedel"; + + using MessageSender::MessageSender; + + virtual void Send(XLine *) anope_abstract; +}; + +// Nick ban (and sometimes channel) +class SQLine : public MessageSender<SQLine> +{ + public: + static constexpr const char *NAME = "sqline"; + + using MessageSender::MessageSender; + + virtual void Send(User *, XLine *) anope_abstract; +}; + +class SQLineDel : public MessageSender<SQLineDel> +{ + public: + static constexpr const char *NAME = "sqlinedel"; + + using MessageSender::MessageSender; + + virtual void Send(XLine *) anope_abstract; +}; + +// IP ban +class SZLine : public MessageSender<SZLine> +{ + public: + static constexpr const char *NAME = "szline"; + + using MessageSender::MessageSender; + + virtual void Send(User *, XLine *) anope_abstract; +}; + +class SZLineDel : public MessageSender<SZLineDel> +{ + public: + static constexpr const char *NAME = "szlinedel"; + + using MessageSender::MessageSender; + + virtual void Send(XLine *) anope_abstract; +}; + +class SQuit : public MessageSender<SQuit> +{ + public: + static constexpr const char *NAME = "squit"; + + using MessageSender::MessageSender; + + virtual void Send(Server *s, const Anope::string &message) anope_abstract; +}; + +class SVSHold : public MessageSender<SVSHold> +{ + public: + static constexpr const char *NAME = "svshold"; + + using MessageSender::MessageSender; + + virtual void Send(const Anope::string &, time_t) anope_abstract; +}; + +class SVSHoldDel : public MessageSender<SVSHoldDel> +{ + public: + static constexpr const char *NAME = "svsholddel"; + + using MessageSender::MessageSender; + + virtual void Send(const Anope::string &) anope_abstract; +}; + +class SVSJoin : public MessageSender<SVSJoin> +{ + public: + static constexpr const char *NAME = "svsjoin"; + + using MessageSender::MessageSender; + + /** Force joins a user that isn't ours to a channel. + * @param bi The source of the message + * @param u The user to join + * @param chan The channel to join the user to + * @param key Channel key + */ + virtual void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) anope_abstract; +}; + +class SVSNick : public MessageSender<SVSNick> +{ + public: + static constexpr const char *NAME = "svsnick"; + + using MessageSender::MessageSender; + + virtual void Send(User *u, const Anope::string &newnick, time_t ts) anope_abstract; +}; + +class SVSPart : public MessageSender<SVSPart> +{ + public: + static constexpr const char *NAME = "svspart"; + + using MessageSender::MessageSender; + + /** Force parts a user that isn't ours from a channel. + * @param source The source of the message + * @param u The user to part + * @param chan The channel to part the user from + * @param param part reason, some IRCds don't support this + */ + virtual void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &reason) anope_abstract; +}; + +class SVSLogin : public MessageSender<SVSLogin> +{ + public: + static constexpr const char *NAME = "svslogin"; + + using MessageSender::MessageSender; + + virtual void Send(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) anope_abstract; +}; + +class SWhois : public MessageSender<SWhois> +{ + public: + static constexpr const char *NAME = "swhois"; + + using MessageSender::MessageSender; + + virtual void Send(const MessageSource &, User *user, const Anope::string &) anope_abstract; +}; + +class Topic : public MessageSender<Topic> +{ + public: + static constexpr const char *NAME = "topic"; + + using MessageSender::MessageSender; + + /** Sets the topic on a channel + * @param source The bot to set the topic from + * @param chan The channel to set the topic on + * @param topic The new topic + * @param topic_ts The desired time set for the new topic + * @param topic_setter Who set the topic + */ + virtual void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) anope_abstract; +}; + +class VhostDel : public MessageSender<VhostDel> +{ + public: + static constexpr const char *NAME = "vhostdel"; + + using MessageSender::MessageSender; + + virtual void Send(User *u) anope_abstract; +}; + +class VhostSet : public MessageSender<VhostSet> +{ + public: + static constexpr const char *NAME = "vhostset"; + + using MessageSender::MessageSender; + + /** Sets a vhost on a user. + * @param u The user + * @param vident The ident to set + * @param vhost The vhost to set + */ + virtual void Send(User *u, const Anope::string &vident, const Anope::string &vhost) anope_abstract; +}; + +class Wallops : public MessageSender<Wallops> +{ + public: + static constexpr const char *NAME = "wallops"; + + using MessageSender::MessageSender; + + virtual void Send(const MessageSource &source, const Anope::string &msg) anope_abstract; +}; + +} // namespace messages diff --git a/include/module.h b/include/module.h index 58b012fce..66446105a 100644 --- a/include/module.h +++ b/include/module.h @@ -32,6 +32,7 @@ #include "lists.h" #include "logger.h" #include "mail.h" +#include "messages.h" #include "modes.h" #include "modules.h" #include "numeric.h" diff --git a/include/modules/protocol/bahamut.h b/include/modules/protocol/bahamut.h index f120c7d4c..fd0d47c87 100644 --- a/include/modules/protocol/bahamut.h +++ b/include/modules/protocol/bahamut.h @@ -22,62 +22,201 @@ namespace bahamut { -class Proto : public IRCDProto +namespace senders +{ + +class Akill : public messages::Akill { public: - Proto(Module *creator); + using messages::Akill::Akill; - void SendMode(const MessageSource &source, Channel *dest, const Anope::string &buf) override; + void Send(User *, XLine *) override; +}; - void SendMode(const MessageSource &source, User *u, const Anope::string &buf) override; +class AkillDel : public messages::AkillDel +{ + public: + using messages::AkillDel::AkillDel; - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override; + void Send(XLine *) override; +}; + +class MessageChannel : public messages::MessageChannel +{ + public: + using messages::MessageChannel::MessageChannel; + + void Send(Channel *) override; +}; - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override; +class Join : public messages::Join +{ + public: + using messages::Join::Join; + + void Send(User *u, Channel *c, const ChannelStatus *status) override; +}; + +class Kill : public messages::Kill +{ + public: + using messages::Kill::Kill; + + void Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) override; + + void Send(const MessageSource &source, User *user, const Anope::string &reason) override; +}; + +class Login : public messages::Login +{ + public: + using messages::Login::Login; - void SendSVSHold(const Anope::string &nick, time_t time) override; + void Send(User *u, NickServ::Nick *na) override; +}; - void SendSVSHoldDel(const Anope::string &nick) override; +class Logout : public messages::Logout +{ + public: + using messages::Logout::Logout; - void SendSQLine(User *, XLine *x) override; + void Send(User *u) override; +}; - void SendSGLineDel(XLine *x) override; +class ModeChannel : public messages::ModeChannel +{ + public: + using messages::ModeChannel::ModeChannel; - void SendSZLineDel(XLine *x) override; + void Send(const MessageSource &source, Channel *channel, const Anope::string &modes) override; +}; - void SendSZLine(User *, XLine *x) override; +class ModeUser : public messages::ModeUser +{ + public: + using messages::ModeUser::ModeUser; - void SendSVSNOOP(Server *server, bool set) override; + void Send(const MessageSource &source, User *user, const Anope::string &modes) override; +}; - void SendSGLine(User *, XLine *x) override; +class NickIntroduction : public messages::NickIntroduction +{ + public: + using messages::NickIntroduction::NickIntroduction; - void SendAkillDel(XLine *x) override; + void Send(User *user) override; +}; - void SendTopic(const MessageSource &source, Channel *c) override; +class NOOP : public messages::NOOP +{ + public: + static constexpr const char *NAME = "noop"; - void SendSQLineDel(XLine *x) override; + using messages::NOOP::NOOP; - void SendJoin(User *user, Channel *c, const ChannelStatus *status) override; + void Send(Server *s, bool mode) override; +}; - void SendAkill(User *u, XLine *x) override; +class SGLine : public messages::SGLine +{ + public: + using messages::SGLine::SGLine; - void SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) override; + void Send(User *, XLine *) override; +}; - void SendBOB() override; +class SGLineDel : public messages::SGLineDel +{ + public: + using messages::SGLineDel::SGLineDel; - void SendEOB() override; + void Send(XLine *) override; +}; - void SendClientIntroduction(User *u) override; +class SQLine : public messages::SQLine +{ + public: + using messages::SQLine::SQLine; + + void Send(User *, XLine *) override; +}; + +class SQLineDel : public messages::SQLineDel +{ + public: + using messages::SQLineDel::SQLineDel; + + void Send(XLine *) override; +}; + +class SZLine : public messages::SZLine +{ + public: + using messages::SZLine::SZLine; + + void Send(User *, XLine *) override; +}; + +class SZLineDel : public messages::SZLineDel +{ + public: + using messages::SZLineDel::SZLineDel; + + void Send(XLine *) override; +}; + +class SVSHold : public messages::SVSHold +{ + public: + using messages::SVSHold::SVSHold; + + void Send(const Anope::string &, time_t) override; +}; + +class SVSHoldDel : public messages::SVSHoldDel +{ + public: + using messages::SVSHoldDel::SVSHoldDel; - void SendServer(Server *server) override; + void Send(const Anope::string &) override; +}; - void SendConnect() override; +class SVSNick : public messages::SVSNick +{ + public: + using messages::SVSNick::SVSNick; - void SendChannel(Channel *c) override; + void Send(User *u, const Anope::string &newnick, time_t ts) override; +}; - void SendLogin(User *u, NickServ::Nick *) override; +class Topic : public messages::Topic +{ + public: + using messages::Topic::Topic; + + void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) override; +}; + +class Wallops : public messages::Wallops +{ + public: + using messages::Wallops::Wallops; + + void Send(const MessageSource &source, const Anope::string &msg) override; +}; + +} // namespace senders + +class Proto : public IRCDProto +{ + public: + Proto(Module *creator); + + void SendBOB() override; + + void SendEOB() override; - void SendLogout(User *u) override; + void Handshake() override; }; class Burst : public IRCDMessage diff --git a/include/modules/protocol/charybdis.h b/include/modules/protocol/charybdis.h index ee81a60a1..f3c06bfeb 100644 --- a/include/modules/protocol/charybdis.h +++ b/include/modules/protocol/charybdis.h @@ -19,53 +19,91 @@ #pragma once +#include "modules/protocol/ts6.h" +#include "modules/protocol/ratbox.h" + namespace charybdis { -class Proto : public IRCDProto +namespace senders { - ServiceReference<IRCDProto> ratbox; // XXX +class NickIntroduction : public messages::NickIntroduction +{ public: - Proto(Module *creator); + using messages::NickIntroduction::NickIntroduction; - void SendSVSKill(const MessageSource &source, User *targ, const Anope::string &reason) override { ratbox->SendSVSKill(source, targ, reason); } - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override { ratbox->SendGlobalNotice(bi, dest, msg); } - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override { ratbox->SendGlobalPrivmsg(bi, dest, msg); } - void SendGlobops(const MessageSource &source, const Anope::string &buf) override { ratbox->SendGlobops(source, buf); } - void SendSGLine(User *u, XLine *x) override { ratbox->SendSGLine(u, x); } - void SendSGLineDel(XLine *x) override { ratbox->SendSGLineDel(x); } - void SendAkill(User *u, XLine *x) override { ratbox->SendAkill(u, x); } - void SendAkillDel(XLine *x) override { ratbox->SendAkillDel(x); } - void SendSQLine(User *u, XLine *x) override { ratbox->SendSQLine(u, x); } - void SendSQLineDel(XLine *x) override { ratbox->SendSQLineDel(x); } - void SendJoin(User *user, Channel *c, const ChannelStatus *status) override { ratbox->SendJoin(user, c, status); } - void SendServer(Server *server) override { ratbox->SendServer(server); } - void SendChannel(Channel *c) override { ratbox->SendChannel(c); } - void SendTopic(const MessageSource &source, Channel *c) override { ratbox->SendTopic(source, c); } - bool IsIdentValid(const Anope::string &ident) override { return ratbox->IsIdentValid(ident); } - void SendLogin(User *u, NickServ::Nick *na) override { ratbox->SendLogin(u, na); } - void SendLogout(User *u) override { ratbox->SendLogout(u); } + void Send(User *user) override; +}; - void SendConnect() override; +class SASL : public messages::SASL +{ + public: + using messages::SASL::SASL; - void SendClientIntroduction(User *u) override; + void Send(const ::SASL::Message &) override; +}; - void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override; +class SASLMechanisms : public messages::SASLMechanisms +{ + public: + using messages::SASLMechanisms::SASLMechanisms; - void SendSVSHold(const Anope::string &nick, time_t delay) override; + void Send(const std::vector<Anope::string> &mechanisms) override; +}; - void SendSVSHoldDel(const Anope::string &nick) override; +class SVSHold : public messages::SVSHold +{ + public: + using messages::SVSHold::SVSHold; - void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) override; + void Send(const Anope::string &, time_t) override; +}; - void SendVhostDel(User *u) override; +class SVSHoldDel : public messages::SVSHoldDel +{ + public: + using messages::SVSHoldDel::SVSHoldDel; - void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) override; + void Send(const Anope::string &) override; +}; + +class SVSLogin : public messages::SVSLogin +{ + public: + using messages::SVSLogin::SVSLogin; + + void Send(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override; +}; + +class VhostDel : public messages::VhostDel +{ + public: + using messages::VhostDel::VhostDel; + + void Send(User *u) override; +}; + +class VhostSet : public messages::VhostSet +{ + public: + using messages::VhostSet::VhostSet; + + void Send(User *u, const Anope::string &vident, const Anope::string &vhost) override; +}; + +} // namespace senders + +class Proto : public ts6::Proto +{ + ratbox::Proto ratbox; + + public: + Proto(Module *creator); - void SendSASLMessage(const SASL::Message &message) override; + bool IsIdentValid(const Anope::string &ident) override { return ratbox.IsIdentValid(ident); } - void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override; + void Handshake() override; }; class Encap : public IRCDMessage diff --git a/include/modules/protocol/hybrid.h b/include/modules/protocol/hybrid.h index a0a9143a8..7843859c0 100644 --- a/include/modules/protocol/hybrid.h +++ b/include/modules/protocol/hybrid.h @@ -20,74 +20,242 @@ #pragma once #include "modules/protocol/rfc1459.h" +#include "modules/protocol/ts6.h" namespace hybrid { -class Proto : public IRCDProto +namespace senders { - ServiceBot *FindIntroduced(); - void SendSVSKill(const MessageSource &source, User *u, const Anope::string &buf) override; +class Akill : public messages::Akill +{ + public: + using messages::Akill::Akill; - public: - Proto(Module *creator); + void Send(User *, XLine *) override; +}; - void SendInvite(const MessageSource &source, Channel *c, User *u) override; +class AkillDel : public messages::AkillDel +{ + public: + using messages::AkillDel::AkillDel; - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override; + void Send(XLine *) override; +}; - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override; +class MessageChannel : public messages::MessageChannel +{ + public: + using messages::MessageChannel::MessageChannel; - void SendSQLine(User *, XLine *x) override; + void Send(Channel *) override; +}; - void SendSGLineDel(XLine *x) override; +class GlobalNotice : public messages::GlobalNotice +{ + public: + using messages::GlobalNotice::GlobalNotice; - void SendSGLine(User *, XLine *x) override; + void Send(const MessageSource &, Server *dest, const Anope::string &msg) override; +}; - void SendSZLineDel(XLine *x) override; +class GlobalPrivmsg : public messages::GlobalPrivmsg +{ + public: + using messages::GlobalPrivmsg::GlobalPrivmsg; - void SendSZLine(User *, XLine *x) override; + void Send(const MessageSource &, Server *dest, const Anope::string &msg) override; +}; - void SendAkillDel(XLine *x) override; +class Invite : public messages::Invite +{ + public: + using messages::Invite::Invite; - void SendSQLineDel(XLine *x) override; + void Send(const MessageSource &source, Channel *chan, User *user) override; +}; - void SendJoin(User *u, Channel *c, const ChannelStatus *status) override; +class Join : public messages::Join +{ + public: + using messages::Join::Join; - void SendAkill(User *u, XLine *x) override; + void Send(User *u, Channel *c, const ChannelStatus *status) override; +}; - void SendServer(Server *server) override; +class Login : public messages::Login +{ + public: + using messages::Login::Login; - void SendConnect() override; + void Send(User *u, NickServ::Nick *na) override; +}; - void SendClientIntroduction(User *u) override; +class Logout : public messages::Logout +{ + public: + using messages::Logout::Logout; - void SendEOB() override; + void Send(User *u) override; +}; + +class ModeUser : public messages::ModeUser +{ + public: + using messages::ModeUser::ModeUser; - void SendMode(const MessageSource &source, User *u, const Anope::string &buf) override; + void Send(const MessageSource &source, User *user, const Anope::string &modes) override; +}; + +class NickIntroduction : public messages::NickIntroduction +{ + public: + using messages::NickIntroduction::NickIntroduction; + + void Send(User *user) override; +}; + +class MessageServer : public messages::MessageServer +{ + public: + using messages::MessageServer::MessageServer; + + void Send(Server *server) override; +}; - void SendLogin(User *u, NickServ::Nick *na) override; +class SGLine : public messages::SGLine +{ + public: + using messages::SGLine::SGLine; - void SendLogout(User *u) override; + void Send(User *, XLine *) override; +}; - void SendChannel(Channel *c) override; +class SGLineDel : public messages::SGLineDel +{ + public: + using messages::SGLineDel::SGLineDel; - void SendTopic(const MessageSource &source, Channel *c) override; + void Send(XLine *) override; +}; - void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override; +class SQLine : public messages::SQLine +{ + public: + using messages::SQLine::SQLine; - void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) override; + void Send(User *, XLine *) override; +}; - void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) override; +class SQLineDel : public messages::SQLineDel +{ + public: + using messages::SQLineDel::SQLineDel; - void SendSVSHold(const Anope::string &nick, time_t t) override; + void Send(XLine *) override; +}; - void SendSVSHoldDel(const Anope::string &nick) override; +class SZLine : public messages::SZLine +{ + public: + using messages::SZLine::SZLine; - void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) override; + void Send(User *, XLine *) override; +}; - void SendVhostDel(User *u) override; +class SZLineDel : public messages::SZLineDel +{ + public: + using messages::SZLineDel::SZLineDel; + + void Send(XLine *) override; +}; + +class SVSHold : public messages::SVSHold +{ + public: + using messages::SVSHold::SVSHold; + + void Send(const Anope::string &, time_t) override; +}; + +class SVSHoldDel : public messages::SVSHoldDel +{ + public: + using messages::SVSHoldDel::SVSHoldDel; + + void Send(const Anope::string &) override; +}; + +class SVSJoin : public messages::SVSJoin +{ + public: + using messages::SVSJoin::SVSJoin; + + void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) override; +}; + +class SVSNick : public messages::SVSNick +{ + public: + using messages::SVSNick::SVSNick; + + void Send(User *u, const Anope::string &newnick, time_t ts) override; +}; + +class SVSPart : public messages::SVSPart +{ + public: + using messages::SVSPart::SVSPart; + + void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &reason) override; +}; + +class Topic : public messages::Topic +{ + public: + using messages::Topic::Topic; + + void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) override; +}; + +class VhostDel : public messages::VhostDel +{ + public: + using messages::VhostDel::VhostDel; + + void Send(User *u) override; +}; + +class VhostSet : public messages::VhostSet +{ + public: + using messages::VhostSet::VhostSet; + + void Send(User *u, const Anope::string &vident, const Anope::string &vhost) override; +}; + +class Wallops : public messages::Wallops +{ + public: + using messages::Wallops::Wallops; + + void Send(const MessageSource &source, const Anope::string &msg) override; +}; + +} // namespace senders + +class Proto : public ts6::Proto +{ + ServiceBot *FindIntroduced(); + + public: + Proto(Module *creator); + + void Handshake() override; + + void SendEOB() override; bool IsIdentValid(const Anope::string &ident) override; }; diff --git a/include/modules/protocol/inspircd20.h b/include/modules/protocol/inspircd20.h index f2126a931..391a0bc79 100644 --- a/include/modules/protocol/inspircd20.h +++ b/include/modules/protocol/inspircd20.h @@ -19,88 +19,270 @@ #pragma once +#include "modules/protocol/ts6.h" + namespace inspircd20 { -class Proto : public IRCDProto +class Proto; + +namespace senders { - private: - void SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) override; - void SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent); +class Akill : public messages::Akill +{ + Proto *proto = nullptr; - void SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost); + public: + Akill(Module *creator, Proto *p) : messages::Akill(creator), + proto(p) + { + } - void SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason); + void Send(User *, XLine *) override; +}; - void SendDelLine(const Anope::string &xtype, const Anope::string &mask); +class AkillDel : public messages::AkillDel +{ + Proto *proto = nullptr; public: - Proto(Module *creator); + AkillDel(Module *creator, Proto *p) : messages::AkillDel(creator), + proto(p) + { + } - void SendConnect() override; + void Send(XLine *) override; +}; - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override; +class MessageChannel : public messages::MessageChannel +{ + public: + using messages::MessageChannel::MessageChannel; - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override; + void Send(Channel *) override; +}; - void SendAkillDel(XLine *x) override; +class Join : public messages::Join +{ + public: + using messages::Join::Join; - void SendTopic(const MessageSource &source, Channel *c) override; + void Send(User *u, Channel *c, const ChannelStatus *status) override; +}; - void SendVhostDel(User *u) override; +class Login : public messages::Login +{ + public: + using messages::Login::Login; - void SendAkill(User *u, XLine *x) override; + void Send(User *u, NickServ::Nick *na) override; +}; - void SendNumeric(int numeric, User *dest, IRCMessage &message); +class Logout : public messages::Logout +{ + public: + using messages::Logout::Logout; - void SendMode(const MessageSource &source, Channel *dest, const Anope::string &buf) override; + void Send(User *u) override; +}; - void SendClientIntroduction(User *u) override; +class ModeChannel : public messages::ModeChannel +{ + public: + using messages::ModeChannel::ModeChannel; - void SendServer(Server *server) override; + void Send(const MessageSource &source, Channel *channel, const Anope::string &modes) override; +}; - void SendSquit(Server *s, const Anope::string &message) override; +class NickIntroduction : public messages::NickIntroduction +{ + public: + using messages::NickIntroduction::NickIntroduction; - void SendJoin(User *user, Channel *c, const ChannelStatus *status) override; + void Send(User *user) override; +}; - void SendSQLineDel(XLine *x) override; +class MessageServer : public messages::MessageServer +{ + public: + using messages::MessageServer::MessageServer; - void SendSQLine(User *, XLine *x) override; + void Send(Server *server) override; +}; - void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) override; +class SASL : public messages::SASL +{ + public: + using messages::SASL::SASL; - void SendSVSHold(const Anope::string &nick, time_t t) override; + void Send(const ::SASL::Message &) override; +}; - void SendSVSHoldDel(const Anope::string &nick) override; +class SASLMechanisms : public messages::SASLMechanisms +{ + public: + using messages::SASLMechanisms::SASLMechanisms; - void SendSZLineDel(XLine *x) override; + void Send(const std::vector<Anope::string> &mechanisms) override; +}; - void SendSZLine(User *, XLine *x) override; +class SQLine : public messages::SQLine +{ + Proto *proto = nullptr; - void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &) override; + public: + SQLine(Module *creator, Proto *p) : messages::SQLine(creator), + proto(p) + { + } - void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) override; + void Send(User *, XLine *) override; +}; - void SendSWhois(const MessageSource &, const Anope::string &who, const Anope::string &mask) override; +class SQLineDel : public messages::SQLineDel +{ + Proto *proto = nullptr; - void SendBOB() override; + public: + SQLineDel(Module *creator, Proto *p) : messages::SQLineDel(creator), + proto(p) + { + } - void SendEOB() override; + void Send(XLine *) override; +}; + +class SQuit : public messages::SQuit +{ + public: + using messages::SQuit::SQuit; + + void Send(Server *s, const Anope::string &message) override; +}; + +class SZLine : public messages::SZLine +{ + Proto *proto = nullptr; + + public: + SZLine(Module *creator, Proto *p) : messages::SZLine(creator), + proto(p) + { + } + + void Send(User *, XLine *) override; +}; + +class SZLineDel : public messages::SZLineDel +{ + Proto *proto = nullptr; + + public: + SZLineDel(Module *creator, Proto *p) : messages::SZLineDel(creator), + proto(p) + { + } + + void Send(XLine *) override; +}; + +class SVSHold : public messages::SVSHold +{ + public: + using messages::SVSHold::SVSHold; + + void Send(const Anope::string &, time_t) override; +}; + +class SVSHoldDel : public messages::SVSHoldDel +{ + public: + using messages::SVSHoldDel::SVSHoldDel; - void SendGlobops(const MessageSource &source, const Anope::string &buf) override; + void Send(const Anope::string &) override; +}; - void SendLogin(User *u, NickServ::Nick *na) override; +class SVSLogin : public messages::SVSLogin +{ + public: + using messages::SVSLogin::SVSLogin; - void SendLogout(User *u) override; + void Send(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override; +}; - void SendChannel(Channel *c) override; +class SWhois : public messages::SWhois +{ + public: + using messages::SWhois::SWhois; - void SendSASLMechanisms(std::vector<Anope::string> &mechanisms) override; + void Send(const MessageSource &, User *user, const Anope::string &) override; +}; - void SendSASLMessage(const SASL::Message &message) override; +class Topic : public messages::Topic +{ + public: + using messages::Topic::Topic; + + void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) override; +}; + +class VhostDel : public messages::VhostDel +{ + Proto *proto = nullptr; + + public: + VhostDel(Module *creator, Proto *p) : messages::VhostDel(creator), + proto(p) + { + } - void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override; + void Send(User *u) override; +}; + +class VhostSet : public messages::VhostSet +{ + Proto *proto = nullptr; + + public: + VhostSet(Module *creator, Proto *p) : messages::VhostSet(creator), + proto(p) + { + } + + void Send(User *u, const Anope::string &vident, const Anope::string &vhost) override; +}; + +class Wallops : public messages::Wallops +{ + public: + using messages::Wallops::Wallops; + + void Send(const MessageSource &source, const Anope::string &msg) override; +}; + +} // namespace senders + +class Proto : public ts6::Proto +{ + public: + Proto(Module *creator); + + void SendChgIdentInternal(const Anope::string &nick, const Anope::string &vIdent); + + void SendChgHostInternal(const Anope::string &nick, const Anope::string &vhost); + + void SendAddLine(const Anope::string &xtype, const Anope::string &mask, time_t duration, const Anope::string &addedby, const Anope::string &reason); + + void SendDelLine(const Anope::string &xtype, const Anope::string &mask); + + void Handshake() override; + + void SendNumeric(int numeric, User *dest, IRCMessage &message) override; + + void SendBOB() override; + + void SendEOB() override; bool IsExtbanValid(const Anope::string &mask) override; @@ -272,7 +454,7 @@ class ServerMessage : public IRCDMessage class SQuit : public rfc1459::SQuit { public: - SQuit(Module *creator) : rfc1459::SQuit(creator) { } + using rfc1459::SQuit::SQuit; void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override; }; diff --git a/include/modules/protocol/ngircd.h b/include/modules/protocol/ngircd.h index fef637aca..072dfb0f6 100644 --- a/include/modules/protocol/ngircd.h +++ b/include/modules/protocol/ngircd.h @@ -23,46 +23,89 @@ namespace ngircd { -class Proto : public IRCDProto +namespace senders { - void SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) override; +class Akill : public messages::Akill +{ public: - Proto(Module *creator); + using messages::Akill::Akill; + + void Send(User *, XLine *) override; +}; + +class AkillDel : public messages::AkillDel +{ + public: + using messages::AkillDel::AkillDel; + + void Send(XLine *) override; +}; - void SendAkill(User *u, XLine *x) override; +class MessageChannel : public messages::MessageChannel +{ + public: + using messages::MessageChannel::MessageChannel; - void SendAkillDel(XLine *x) override; + void Send(Channel *) override; +}; - void SendChannel(Channel *c) override; +class NickIntroduction : public messages::NickIntroduction +{ + public: + using messages::NickIntroduction::NickIntroduction; + + void Send(User *user) override; +}; - // Received: :dev.anope.de NICK DukeP 1 ~DukePyro p57ABF9C9.dip.t-dialin.net 1 +i :DukePyrolator - void SendClientIntroduction(User *u) override; +class Login : public messages::Login +{ + public: + using messages::Login::Login; - void SendConnect() override; + void Send(User *u, NickServ::Nick *na) override; +}; - void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override; +class Logout : public messages::Logout +{ + public: + using messages::Logout::Logout; - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override; + void Send(User *u) override; +}; - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override; +class SVSNick : public messages::SVSNick +{ + public: + using messages::SVSNick::SVSNick; - void SendGlobops(const MessageSource &source, const Anope::string &buf) override; + void Send(User *u, const Anope::string &newnick, time_t ts) override; +}; - void SendJoin(User *user, Channel *c, const ChannelStatus *status) override; +class VhostDel : public messages::VhostDel +{ + public: + using messages::VhostDel::VhostDel; - void SendLogin(User *u, NickServ::Nick *na) override; + void Send(User *u) override; +}; - void SendLogout(User *u) override; +class VhostSet : public messages::VhostSet +{ + public: + using messages::VhostSet::VhostSet; - /* SERVER name hop descript */ - void SendServer(Server *server) override; + void Send(User *u, const Anope::string &vident, const Anope::string &vhost) override; +}; - void SendTopic(const MessageSource &source, Channel *c) override; +} - void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) override; +class Proto : public IRCDProto +{ + public: + Proto(Module *creator); - void SendVhostDel(User *u) override; + void Handshake() override; Anope::string Format(IRCMessage &message) override; }; @@ -72,7 +115,6 @@ class Numeric005 : public IRCDMessage public: Numeric005(Module *creator) : IRCDMessage(creator, "005", 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } - // Please see <http://www.irc.org/tech_docs/005.html> for details. void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override; }; @@ -168,4 +210,4 @@ class ServerMessage : public IRCDMessage void Run(MessageSource &source, const std::vector<Anope::string> ¶ms) override; }; -} // namespace ngircd
\ No newline at end of file +} // namespace ngircd diff --git a/include/modules/protocol/plexus.h b/include/modules/protocol/plexus.h index 69be3d713..4afbc391e 100644 --- a/include/modules/protocol/plexus.h +++ b/include/modules/protocol/plexus.h @@ -19,55 +19,96 @@ #pragma once +#include "modules/protocol/ts6.h" + namespace plexus { -class Proto : public IRCDProto +namespace senders { - ServiceReference<IRCDProto> hybrid; // XXX use moddeps + inheritance here +class ModeUser : public messages::ModeUser +{ public: - Proto(Module *creator); + using messages::ModeUser::ModeUser; + + void Send(const MessageSource &source, User *user, const Anope::string &modes) override; +}; + +class NickIntroduction : public messages::NickIntroduction +{ + public: + using messages::NickIntroduction::NickIntroduction; + + void Send(User *user) override; +}; + +class NOOP : public messages::NOOP +{ + public: + static constexpr const char *NAME = "noop"; + + using messages::NOOP::NOOP; + + void Send(Server *s, bool mode) override; +}; + +class Topic : public messages::Topic +{ + public: + using messages::Topic::Topic; - void SendSVSKill(const MessageSource &source, User *targ, const Anope::string &reason) override { hybrid->SendSVSKill(source, targ, reason); } - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override { hybrid->SendGlobalNotice(bi, dest, msg); } - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override { hybrid->SendGlobalPrivmsg(bi, dest, msg); } - void SendSQLine(User *u, XLine *x) override { hybrid->SendSQLine(u, x); } - void SendSQLineDel(XLine *x) override { hybrid->SendSQLineDel(x); } - void SendSGLineDel(XLine *x) override { hybrid->SendSGLineDel(x); } - void SendSGLine(User *u, XLine *x) override { hybrid->SendSGLine(u, x); } - void SendAkillDel(XLine *x) override { hybrid->SendAkillDel(x); } - void SendAkill(User *u, XLine *x) override { hybrid->SendAkill(u, x); } - void SendServer(Server *server) override { hybrid->SendServer(server); } - void SendChannel(Channel *c) override { hybrid->SendChannel(c); } - void SendSVSHold(const Anope::string &nick, time_t t) override { hybrid->SendSVSHold(nick, t); } - void SendSVSHoldDel(const Anope::string &nick) override { hybrid->SendSVSHoldDel(nick); } + void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) override; +}; - void SendGlobops(const MessageSource &source, const Anope::string &buf) override; +class SVSJoin : public messages::SVSJoin +{ + public: + using messages::SVSJoin::SVSJoin; - void SendJoin(User *user, Channel *c, const ChannelStatus *status) override; + void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) override; +}; - void SendForceNickChange(User *u, const Anope::string &newnick, time_t when) override; +class SVSNick : public messages::SVSNick +{ + public: + using messages::SVSNick::SVSNick; - void SendVhost(User *u, const Anope::string &ident, const Anope::string &host) override; + void Send(User *u, const Anope::string &newnick, time_t ts) override; +}; - void SendVhostDel(User *u) override; +class SVSPart : public messages::SVSPart +{ + public: + using messages::SVSPart::SVSPart; - void SendConnect() override; + void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &reason) override; +}; - void SendClientIntroduction(User *u) override; +class VhostDel : public messages::VhostDel +{ + public: + using messages::VhostDel::VhostDel; - void SendMode(const MessageSource &source, User *u, const Anope::string &buf) override; + void Send(User *u) override; +}; - void SendLogin(User *u, NickServ::Nick *na) override; +class VhostSet : public messages::VhostSet +{ + public: + using messages::VhostSet::VhostSet; - void SendLogout(User *u) override; + void Send(User *u, const Anope::string &vident, const Anope::string &vhost) override; +}; - void SendTopic(const MessageSource &source, Channel *c) override; +} // namespace senders - void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) override; +class Proto : public ts6::Proto +{ + public: + Proto(Module *creator); - void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) override; + void Handshake() override; }; class Encap : public IRCDMessage diff --git a/include/modules/protocol/ratbox.h b/include/modules/protocol/ratbox.h index ba7a7f19f..475b368cc 100644 --- a/include/modules/protocol/ratbox.h +++ b/include/modules/protocol/ratbox.h @@ -20,47 +20,92 @@ #pragma once #include "modules/protocol/rfc1459.h" +#include "modules/protocol/ts6.h" namespace ratbox { -class Proto : public IRCDProto +namespace senders { - ServiceReference<IRCDProto> hybrid; // XXX - ServiceBot *FindIntroduced(); +class Login : public messages::Login +{ + public: + using messages::Login::Login; + + void Send(User *u, NickServ::Nick *na) override; +}; +class Logout : public messages::Logout +{ public: - Proto(Module *creator); + using messages::Logout::Logout; + + void Send(User *u) override; +}; + +class NickIntroduction : public messages::NickIntroduction +{ + public: + using messages::NickIntroduction::NickIntroduction; + + void Send(User *user) override; +}; + +class SQLine : public messages::SQLine +{ + public: + using messages::SQLine::SQLine; + + void Send(User *, XLine *) override; +}; + +class SQLineDel : public messages::SQLineDel +{ + public: + using messages::SQLineDel::SQLineDel; + + void Send(XLine *) override; +}; + +class SVSNick : public messages::SVSNick +{ + public: + using messages::SVSNick::SVSNick; + + void Send(User *u, const Anope::string &newnick, time_t ts) override; +}; + +class Topic : public rfc1459::senders::Topic +{ + public: + using rfc1459::senders::Topic::Topic; - void SendSVSKill(const MessageSource &source, User *targ, const Anope::string &reason) override { hybrid->SendSVSKill(source, targ, reason); } - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override { hybrid->SendGlobalNotice(bi, dest, msg); } - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override { hybrid->SendGlobalPrivmsg(bi, dest, msg); } - void SendSGLine(User *u, XLine *x) override { hybrid->SendSGLine(u, x); } - void SendSGLineDel(XLine *x) override { hybrid->SendSGLineDel(x); } - void SendAkill(User *u, XLine *x) override { hybrid->SendAkill(u, x); } - void SendAkillDel(XLine *x) override { hybrid->SendAkillDel(x); } - void SendJoin(User *user, Channel *c, const ChannelStatus *status) override { hybrid->SendJoin(user, c, status); } - void SendServer(Server *server) override { hybrid->SendServer(server); } - void SendMode(const MessageSource &source, User *u, const Anope::string &buf) override { hybrid->SendMode(source, u, buf); } - void SendChannel(Channel *c) override { hybrid->SendChannel(c); } - bool IsIdentValid(const Anope::string &ident) override { return hybrid->IsIdentValid(ident); } + void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) override; +}; - void SendGlobops(const MessageSource &source, const Anope::string &buf) override; +class Wallops : public messages::Wallops +{ + public: + using messages::Wallops::Wallops; - void SendConnect() override; + void Send(const MessageSource &source, const Anope::string &msg) override; +}; - void SendClientIntroduction(User *u) override; +} // senders - void SendLogin(User *u, NickServ::Nick *na) override; +class Proto : public ts6::Proto +{ + hybrid::Proto hybrid; - void SendLogout(User *u) override; + ServiceBot *FindIntroduced(); - void SendTopic(const MessageSource &source, Channel *c) override; + public: + Proto(Module *creator); - void SendSQLine(User *, XLine *x) override; + bool IsIdentValid(const Anope::string &ident) override { return hybrid.IsIdentValid(ident); } - void SendSQLineDel(XLine *x) override; + void Handshake() override; }; class Encap : public IRCDMessage diff --git a/include/modules/protocol/rfc1459.h b/include/modules/protocol/rfc1459.h index 4ef8f0313..54c4bada5 100644 --- a/include/modules/protocol/rfc1459.h +++ b/include/modules/protocol/rfc1459.h @@ -22,6 +22,165 @@ namespace rfc1459 { +namespace senders +{ + +class GlobalNotice : public messages::GlobalNotice +{ + public: + using messages::GlobalNotice::GlobalNotice; + + void Send(const MessageSource &, Server *dest, const Anope::string &msg) override; +}; + +class GlobalPrivmsg : public messages::GlobalPrivmsg +{ + public: + using messages::GlobalPrivmsg::GlobalPrivmsg; + + void Send(const MessageSource &, Server *dest, const Anope::string &msg) override; +}; + +class Invite : public messages::Invite +{ + public: + using messages::Invite::Invite; + + void Send(const MessageSource &source, Channel *chan, User *user) override; +}; + +class Join : public messages::Join +{ + public: + using messages::Join::Join; + + void Send(User *u, Channel *c, const ChannelStatus *status) override; +}; + +class Kick : public messages::Kick +{ + public: + using messages::Kick::Kick; + + void Send(const MessageSource &source, Channel *chan, User *user, const Anope::string &reason) override; +}; + +class Kill : public messages::Kill +{ + public: + using messages::Kill::Kill; + + void Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) override; + + void Send(const MessageSource &source, User *user, const Anope::string &reason) override; +}; + +class ModeChannel : public messages::ModeChannel +{ + public: + using messages::ModeChannel::ModeChannel; + + void Send(const MessageSource &source, Channel *channel, const Anope::string &modes) override; +}; + +class ModeUser : public messages::ModeUser +{ + public: + using messages::ModeUser::ModeUser; + + void Send(const MessageSource &source, User *user, const Anope::string &modes) override; +}; + +class NickChange : public messages::NickChange +{ + public: + using messages::NickChange::NickChange; + + void Send(User *u, const Anope::string &newnick, time_t ts) override; +}; + +class Notice : public messages::Notice +{ + public: + using messages::Notice::Notice; + + void Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) override; +}; + +class Part : public messages::Part +{ + public: + using messages::Part::Part; + + void Send(User *, Channel *chan, const Anope::string &reason) override; +}; + +class Ping : public messages::Ping +{ + public: + using messages::Ping::Ping; + + void Send(const Anope::string &servname, const Anope::string &who) override; +}; + +class Pong : public messages::Pong +{ + public: + using messages::Pong::Pong; + + void Send(const Anope::string &servname, const Anope::string &who) override; +}; + +class Privmsg : public messages::Privmsg +{ + public: + using messages::Privmsg::Privmsg; + + void Send(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) override; +}; + +class Quit : public messages::Quit +{ + public: + using messages::Quit::Quit; + + void Send(User *user, const Anope::string &reason) override; +}; + +class MessageServer : public messages::MessageServer +{ + public: + using messages::MessageServer::MessageServer; + + void Send(Server *server) override; +}; + +class SQuit : public messages::SQuit +{ + public: + using messages::SQuit::SQuit; + + void Send(Server *s, const Anope::string &message) override; +}; + +class Topic : public messages::Topic +{ + public: + using messages::Topic::Topic; + + void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) override; +}; + +class Wallops : public messages::Wallops +{ + public: + using messages::Wallops::Wallops; + + void Send(const MessageSource &, const Anope::string &msg) override; +}; + +} // namespace senders + class Away : public IRCDMessage { public: diff --git a/include/modules/protocol/ts6.h b/include/modules/protocol/ts6.h new file mode 100644 index 000000000..71748b5b7 --- /dev/null +++ b/include/modules/protocol/ts6.h @@ -0,0 +1,37 @@ +/* + * 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/>. + */ + +#pragma once + +namespace ts6 +{ + +class Proto : public IRCDProto +{ + public: + Proto(Module *creator, const Anope::string &proto_name) : IRCDProto(creator, proto_name) + { + } + + /* Retrieves the next free UID or SID */ + Anope::string UID_Retrieve() override; + Anope::string SID_Retrieve() override; +}; + +} // namespace ts6 diff --git a/include/modules/protocol/unreal.h b/include/modules/protocol/unreal.h index 0a01cb4be..9039cc2cd 100644 --- a/include/modules/protocol/unreal.h +++ b/include/modules/protocol/unreal.h @@ -22,79 +22,237 @@ namespace unreal { -class Proto : public IRCDProto +namespace senders +{ + +class Akill : public messages::Akill { public: - Proto(Module *creator); + using messages::Akill::Akill; - private: - void SendSVSNOOP(Server *server, bool set) override; + void Send(User *, XLine *) override; +}; + +class AkillDel : public messages::AkillDel +{ + public: + using messages::AkillDel::AkillDel; + + void Send(XLine *) override; +}; + +class MessageChannel : public messages::MessageChannel +{ + public: + using messages::MessageChannel::MessageChannel; + + void Send(Channel *) override; +}; - void SendAkillDel(XLine *x) override; +class Join : public messages::Join +{ + public: + using messages::Join::Join; - void SendTopic(const MessageSource &source, Channel *c) override; + void Send(User *u, Channel *c, const ChannelStatus *status) override; +}; - void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) override; +class Login : public messages::Login +{ + public: + using messages::Login::Login; - void SendGlobalPrivmsg(ServiceBot *bi, Server *dest, const Anope::string &msg) override; + void Send(User *u, NickServ::Nick *na) override; +}; - void SendVhostDel(User *u) override; +class Logout : public messages::Logout +{ + public: + using messages::Logout::Logout; - void SendAkill(User *u, XLine *x) override; + void Send(User *u) override; +}; - void SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) override; +class Kill : public messages::Kill +{ + public: + using messages::Kill::Kill; - void SendMode(const MessageSource &source, User *u, const Anope::string &buf) override; + void Send(const MessageSource &source, const Anope::string &target, const Anope::string &reason) override; - void SendClientIntroduction(User *u) override; + void Send(const MessageSource &source, User *user, const Anope::string &reason) override; +}; - void SendServer(Server *server) override; +class ModeUser : public messages::ModeUser +{ + public: + using messages::ModeUser::ModeUser; - void SendJoin(User *user, Channel *c, const ChannelStatus *status) override; + void Send(const MessageSource &source, User *user, const Anope::string &modes) override; +}; - void SendSQLineDel(XLine *x) override; +class NickIntroduction : public messages::NickIntroduction +{ + public: + using messages::NickIntroduction::NickIntroduction; - void SendSQLine(User *, XLine *x) override; + void Send(User *user) override; +}; - void SendVhost(User *u, const Anope::string &vIdent, const Anope::string &vhost) override; +class SASL : public messages::SASL +{ + public: + using messages::SASL::SASL; - void SendConnect() override; + void Send(const ::SASL::Message &) override; +}; - void SendSVSHold(const Anope::string &nick, time_t t) override; +class MessageServer : public messages::MessageServer +{ + public: + using messages::MessageServer::MessageServer; - void SendSVSHoldDel(const Anope::string &nick) override; + void Send(Server *server) override; +}; - void SendSGLineDel(XLine *x) override; +class SGLine : public messages::SGLine +{ + public: + using messages::SGLine::SGLine; - void SendSZLineDel(XLine *x) override; + void Send(User *, XLine *) override; +}; - void SendSZLine(User *, XLine *x) override; +class SGLineDel : public messages::SGLineDel +{ + public: + using messages::SGLineDel::SGLineDel; - void SendSGLine(User *, XLine *x) override; + void Send(XLine *) override; +}; - void SendSVSJoin(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) override; +class SQLine : public messages::SQLine +{ + public: + using messages::SQLine::SQLine; - void SendSVSPart(const MessageSource &source, User *user, const Anope::string &chan, const Anope::string ¶m) override; + void Send(User *, XLine *) override; +}; - void SendSWhois(const MessageSource &source, const Anope::string &who, const Anope::string &mask) override; +class SQLineDel : public messages::SQLineDel +{ + public: + using messages::SQLineDel::SQLineDel; - void SendEOB() override; + void Send(XLine *) override; +}; - bool IsNickValid(const Anope::string &nick) override; +class SZLine : public messages::SZLine +{ + public: + using messages::SZLine::SZLine; - bool IsChannelValid(const Anope::string &chan) override; + void Send(User *, XLine *) override; +}; - bool IsExtbanValid(const Anope::string &mask) override; +class SZLineDel : public messages::SZLineDel +{ + public: + using messages::SZLineDel::SZLineDel; + + void Send(XLine *) override; +}; + +class SVSHold : public messages::SVSHold +{ + public: + using messages::SVSHold::SVSHold; + + void Send(const Anope::string &, time_t) override; +}; + +class SVSHoldDel : public messages::SVSHoldDel +{ + public: + using messages::SVSHoldDel::SVSHoldDel; + + void Send(const Anope::string &) override; +}; + +class SVSJoin : public messages::SVSJoin +{ + public: + using messages::SVSJoin::SVSJoin; + + void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &key) override; +}; + +class SVSLogin : public messages::SVSLogin +{ + public: + using messages::SVSLogin::SVSLogin; + + void Send(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override; +}; + +class SVSPart : public messages::SVSPart +{ + public: + using messages::SVSPart::SVSPart; + + void Send(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string &reason) override; +}; + +class SWhois : public messages::SWhois +{ + public: + using messages::SWhois::SWhois; + + void Send(const MessageSource &, User *user, const Anope::string &) override; +}; + +class Topic : public messages::Topic +{ + public: + using messages::Topic::Topic; + + void Send(const MessageSource &source, Channel *channel, const Anope::string &topic, time_t topic_ts, const Anope::string &topic_setter) override; +}; + +class VhostDel : public messages::VhostDel +{ + public: + using messages::VhostDel::VhostDel; + + void Send(User *u) override; +}; + +class VhostSet : public messages::VhostSet +{ + public: + using messages::VhostSet::VhostSet; + + void Send(User *u, const Anope::string &vident, const Anope::string &vhost) override; +}; - void SendLogin(User *u, NickServ::Nick *na) override; +} // namespace senders - void SendLogout(User *u) override; +class Proto : public IRCDProto +{ + public: + Proto(Module *creator); - void SendChannel(Channel *c) override; + private: - void SendSASLMessage(const ::SASL::Message &message) override; + void Handshake() override; - void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) override; + void SendEOB() override; + + bool IsNickValid(const Anope::string &nick) override; + + bool IsChannelValid(const Anope::string &chan) override; + + bool IsExtbanValid(const Anope::string &mask) override; bool IsIdentValid(const Anope::string &ident) override; }; diff --git a/include/protocol.h b/include/protocol.h index ee782903b..4dc115fe6 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -24,6 +24,7 @@ #include "service.h" #include "servers.h" #include "users.h" +#include "messages.h" class IRCMessage; @@ -72,168 +73,26 @@ public: virtual void Parse(const Anope::string &, Anope::string &, Anope::string &, std::vector<Anope::string> &); virtual Anope::string Format(IRCMessage &); - /** Kills a user - * @param source Who is doing the kill - * @param user The target to be killed - * @param reason Kill reason - */ - virtual void SendSVSKill(const MessageSource &source, User *user, const Anope::string &reason); - virtual void SendMode(const MessageSource &, Channel *, const Anope::string &); - virtual void SendMode(const MessageSource &, User *, const Anope::string &); - virtual void SendKick(const MessageSource &, Channel *, User *, const Anope::string &); - virtual void SendNotice(const MessageSource &, const Anope::string &dest, const Anope::string &msg); - virtual void SendPrivmsg(const MessageSource &, const Anope::string &dest, const Anope::string &msg); - virtual void SendQuit(User *, const Anope::string &reason); - virtual void SendPart(User *, Channel *chan, const Anope::string &reason); - virtual void SendGlobops(const MessageSource &, const Anope::string &buf); virtual void SendCTCPReply(const MessageSource &, const Anope::string &dest, const Anope::string &buf); virtual void SendNumeric(int numeric, User *dest, IRCMessage &); /* Retrieves the next free UID or SID */ - virtual Anope::string UID_Retrieve(); - virtual Anope::string SID_Retrieve(); - - /** Sets the server in NOOP mode. If NOOP mode is enabled, no users - * will be able to oper on the server. - * @param s The server - * @param mode Whether to turn NOOP on or off - */ - virtual void SendSVSNOOP(Server *s, bool mode) { } - - /** Sets the topic on a channel - * @param bi The bot to set the topic from - * @param c The channel to set the topic on. The topic being set is Channel::topic - */ - virtual void SendTopic(const MessageSource &, Channel *); - - /** Sets a vhost on a user. - * @param u The user - * @param vident The ident to set - * @param vhost The vhost to set - */ - virtual void SendVhost(User *u, const Anope::string &vident, const Anope::string &vhost) { } - virtual void SendVhostDel(User *) { } - - /** Sets an akill. This is a recursive function that can be called multiple times - * for the same xline, but for different users, if the xline is not one that can be - * enforced by the IRCd, such as a nick/user/host/realname combination ban. - * @param u The user affected by the akill, if known - * @param x The akill - */ - virtual void SendAkill(User *, XLine *) anope_abstract; - virtual void SendAkillDel(XLine *) anope_abstract; - - /* Realname ban */ - virtual void SendSGLine(User *, XLine *) { } - virtual void SendSGLineDel(XLine *) { } - - /* IP ban */ - virtual void SendSZLine(User *u, XLine *) { } - virtual void SendSZLineDel(XLine *) { } - - /* Nick ban (and sometimes channel) */ - virtual void SendSQLine(User *, XLine *x) { } - virtual void SendSQLineDel(XLine *x) { } - - virtual void SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason); - - /** Introduces a client to the rest of the network - * @param u The client to introduce - */ - virtual void SendClientIntroduction(User *u) anope_abstract; + virtual Anope::string UID_Retrieve() { return ""; } + virtual Anope::string SID_Retrieve() { return ""; } virtual void SendAction(const MessageSource &source, const Anope::string &dest, const Anope::string &message); - virtual void SendGlobalNotice(ServiceBot *bi, Server *dest, const Anope::string &msg) anope_abstract; - virtual void SendGlobalPrivmsg(ServiceBot *bi, Server *desc, const Anope::string &msg) anope_abstract; - - - virtual void SendPing(const Anope::string &servname, const Anope::string &who); - - /** - * Send a PONG reply to a received PING. - * servname should be left empty to send a one param reply. - * @param servname Daemon or client that is responding to the PING. - * @param who Origin of the PING and destination of the PONG message. - **/ - virtual void SendPong(const Anope::string &servname, const Anope::string &who); - - /** Joins one of our users to a channel. - * @param u The user to join - * @param c The channel to join the user to - * @param status The status to set on the user after joining. This may or may not already internally - * be set on the user. This may include the modes in the join, but will usually place them on the mode - * stacker to be set "soon". - */ - virtual void SendJoin(User *u, Channel *c, const ChannelStatus *status) anope_abstract; - - /** Force joins a user that isn't ours to a channel. - * @param bi The source of the message - * @param u The user to join - * @param chan The channel to join the user to - * @param param Channel key? - */ - virtual void SendSVSJoin(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) { } - - /** Force parts a user that isn't ours from a channel. - * @param source The source of the message - * @param u The user to part - * @param chan The channel to part the user from - * @param param part reason, some IRCds don't support this - */ - virtual void SendSVSPart(const MessageSource &source, User *u, const Anope::string &chan, const Anope::string ¶m) { } - - virtual void SendInvite(const MessageSource &source, Channel *c, User *u); - - - /** Sends a nick change of one of our clients. - */ - virtual void SendNickChange(User *u, const Anope::string &newnick); - - /** Forces a nick change of a user that isn't ours (SVSNICK) - */ - virtual void SendForceNickChange(User *u, const Anope::string &newnick, time_t when); - - /** Used to introduce ourselves to our uplink. Usually will SendServer(Me) and any other - * initial handshake requirements. + /** Used to introduce ourselves to our uplink. */ - virtual void SendConnect() anope_abstract; + virtual void Handshake() anope_abstract; - /** Called right before we begin our burst, after we have handshaked successfully with the uplink/ - * At this point none of our servesr, users, or channels exist on the uplink + /** Called right before we begin our burst, after we have handshaked successfully with the uplink. + * At this point none of our servers, users, or channels exist on the uplink */ virtual void SendBOB() { } virtual void SendEOB() { } - virtual void SendSVSHold(const Anope::string &, time_t) { } - virtual void SendSVSHoldDel(const Anope::string &) { } - - virtual void SendSWhois(const MessageSource &, const Anope::string &, const Anope::string &) { } - - /** Introduces a server to the uplink - */ - virtual void SendServer(Server *) anope_abstract; - virtual void SendSquit(Server *, const Anope::string &message); - - - virtual void SendLogin(User *u, NickServ::Nick *na) anope_abstract; - virtual void SendLogout(User *u) anope_abstract; - - /** Send a channel creation message to the uplink. - * On most TS6 IRCds this is a SJOIN with no nick - */ - virtual void SendChannel(Channel *c) { } - - /** Make the user an IRC operator - * Normally this is a simple +o, though some IRCds require us to send the oper type - */ - virtual void SendOper(User *u); - - virtual void SendSASLMechanisms(std::vector<Anope::string> &) { } - virtual void SendSASLMessage(const SASL::Message &) { } - virtual void SendSVSLogin(const Anope::string &uid, const Anope::string &acc, const Anope::string &vident, const Anope::string &vhost) { } - virtual bool IsNickValid(const Anope::string &); virtual bool IsChannelValid(const Anope::string &); virtual bool IsIdentValid(const Anope::string &); @@ -247,35 +106,48 @@ public: virtual Anope::string NormalizeMask(const Anope::string &mask); + template<typename T, typename... Args> void Send(Args&&... args) + { + ServiceReference<MessageSender<T>> sender(T::NAME); + + if (!sender) + { + Log(LOG_DEBUG) << "No message sender for type " << T::NAME; + return; + } + + static_cast<T*>(static_cast<MessageSender<T>*>(sender))->Send(std::forward<Args>(args)...); + } + /* Templated functions which overload the normal functions to provide format strings */ - template<typename... Args> void SendSVSKill(const MessageSource &source, User *user, const Anope::string &reason, Args&&... args) + template<typename... Args> void SendKill(const MessageSource &source, User *user, const Anope::string &reason, Args&&... args) { - SendSVSKill(source, user, Anope::Format(reason, std::forward<Args>(args)...)); + Send<messages::Kill>(source, user, Anope::Format(reason, std::forward<Args>(args)...)); } template<typename... Args> void SendMode(const MessageSource &source, Channel *chan, const Anope::string &modes, Args&&... args) { - SendMode(source, chan, Anope::Format(modes, std::forward<Args>(args)...)); + Send<messages::ModeChannel>(source, chan, Anope::Format(modes, std::forward<Args>(args)...)); } template<typename... Args> void SendMode(const MessageSource &source, User *u, const Anope::string &modes, Args&&... args) { - SendMode(source, u, Anope::Format(modes, std::forward<Args>(args)...)); + Send<messages::ModeUser>(source, u, Anope::Format(modes, std::forward<Args>(args)...)); } - template<typename... Args> void SendKick(const MessageSource &source, const Channel *chan, User *user, const Anope::string &reason, Args&&... args) + template<typename... Args> void SendKick(const MessageSource &source, Channel *chan, User *user, const Anope::string &reason, Args&&... args) { - SendKick(source, chan, user, Anope::Format(reason, std::forward<Args>(args)...)); + Send<messages::Kick>(source, chan, user, Anope::Format(reason, std::forward<Args>(args)...)); } template<typename... Args> void SendNotice(const MessageSource &source, const Anope::string &dest, const Anope::string &message, Args&&... args) { - SendNotice(source, dest, Anope::Format(message, std::forward<Args>(args)...)); + Send<messages::Notice>(source, dest, Anope::Format(message, std::forward<Args>(args)...)); } template<typename... Args> void SendPrivmsg(const MessageSource &source, const Anope::string &dest, const Anope::string &message, Args&&... args) { - SendPrivmsg(source, dest, Anope::Format(message, std::forward<Args>(args)...)); + Send<messages::Privmsg>(source, dest, Anope::Format(message, std::forward<Args>(args)...)); } template<typename... Args> void SendAction(const MessageSource &source, const Anope::string &dest, const Anope::string &message, Args&&... args) @@ -288,21 +160,21 @@ public: SendCTCPReply(source, dest, Anope::Format(message, std::forward<Args>(args)...)); } - template<typename... Args> void SendGlobops(const MessageSource &source, const Anope::string &msg, Args&&... args) + template<typename... Args> void SendWallops(const MessageSource &source, const Anope::string &msg, Args&&... args) { - SendGlobops(source, Anope::Format(msg, std::forward<Args>(args)...)); + Send<messages::Wallops>(source, Anope::Format(msg, std::forward<Args>(args)...)); } template<typename... Args> void SendNumeric(int numeric, User *dest, Args&&... args); template<typename... Args> void SendQuit(User *u, const Anope::string &reason, Args&&... args) { - SendQuit(u, Anope::Format(reason, std::forward<Args>(args)...)); + Send<messages::Quit>(u, Anope::Format(reason, std::forward<Args>(args)...)); } template<typename... Args> void SendPart(User *u, Channel *chan, const Anope::string &reason, Args&&... args) { - SendPart(u, chan, Anope::Format(reason, std::forward<Args>(args)...)); + Send<messages::Part>(u, chan, Anope::Format(reason, std::forward<Args>(args)...)); } }; @@ -334,10 +206,10 @@ enum IRCDMessageFlag class CoreExport IRCDMessage : public Service { Anope::string name; - unsigned param_count; + unsigned int param_count; std::set<IRCDMessageFlag> flags; public: - static constexpr const char *NAME = "IRCDMessage"; + static constexpr const char *NAME = "ircdmessage"; IRCDMessage(Module *owner, const Anope::string &n, unsigned int p = 0); unsigned int GetParamCount() const; 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); } }; diff --git a/src/bots.cpp b/src/bots.cpp index 091caa12f..dfe46ea67 100644 --- a/src/bots.cpp +++ b/src/bots.cpp @@ -49,7 +49,7 @@ ServiceBot::ServiceBot(const Anope::string &nnick, const Anope::string &nuser, c //XXX //XLine x(this->nick, "Reserved for services"); //IRCD->SendSQLine(NULL, &x); - IRCD->SendClientIntroduction(this); + IRCD->Send<messages::NickIntroduction>(this); this->introduced = true; } } @@ -92,11 +92,11 @@ void ServiceBot::OnKill() { this->introduced = false; this->GenerateUID(); - IRCD->SendClientIntroduction(this); + IRCD->Send<messages::NickIntroduction>(this); this->introduced = true; for (User::ChanUserList::const_iterator cit = this->chans.begin(), cit_end = this->chans.end(); cit != cit_end; ++cit) - IRCD->SendJoin(this, cit->second->chan, &cit->second->status); + IRCD->Send<messages::Join>(this, cit->second->chan, &cit->second->status); } void ServiceBot::SetNewNick(const Anope::string &newnick) @@ -160,7 +160,7 @@ void ServiceBot::Join(Channel *c, ChannelStatus *status) c->JoinUser(this, status); if (IRCD) - IRCD->SendJoin(this, c, status); + IRCD->Send<messages::Join>(this, c, status); EventManager::Get()->Dispatch(&Event::JoinChannel::OnJoinChannel, this, c); } diff --git a/src/channels.cpp b/src/channels.cpp index bb6bc3083..aed6c7b53 100644 --- a/src/channels.cpp +++ b/src/channels.cpp @@ -789,7 +789,7 @@ void Channel::ChangeTopic(const Anope::string &user, const Anope::string &newtop this->topic_setter = user; this->topic_ts = ts; - IRCD->SendTopic(this->ci->WhoSends(), this); + IRCD->Send<messages::Topic>(this->ci->WhoSends(), this, newtopic, ts, user); /* Now that the topic is set update the time set. This is *after* we set it so the protocol modules are able to tell the old last set time */ this->topic_time = Anope::CurTime; diff --git a/src/command.cpp b/src/command.cpp index f1cae4bb3..7a87b07f3 100644 --- a/src/command.cpp +++ b/src/command.cpp @@ -120,7 +120,7 @@ void CommandSource::Reply(const Anope::string &message) this->reply->SendMessage(*this->service, tok); } -Command::Command(Module *o, const Anope::string &sname, size_t minparams, size_t maxparams) : Service(o, "Command", sname), max_params(maxparams), min_params(minparams), module(o) +Command::Command(Module *o, const Anope::string &sname, size_t minparams, size_t maxparams) : Service(o, NAME, sname), max_params(maxparams), min_params(minparams), module(o) { allow_unregistered = require_user = false; } diff --git a/src/logger.cpp b/src/logger.cpp index 4949860a3..2751382f6 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -321,7 +321,7 @@ void LogInfo::OpenLogFiles() { const Anope::string &target = this->targets[i]; - if (target.empty() || target[0] == '#' || target == "globops" || target.find(":") != Anope::string::npos) + if (target.empty() || target[0] == '#' || target == "opers" || target.find(":") != Anope::string::npos) continue; LogFile *lf = new LogFile(CreateLogName(target)); @@ -386,11 +386,11 @@ void LogInfo::ProcessMessage(const Log *l) IRCD->SendPrivmsg(bi, c->name, buffer); } } - else if (target == "globops") + else if (target == "opers") { if (UplinkSock && l->bi && l->type <= LOG_NORMAL && Me && Me->IsSynced()) { - IRCD->SendGlobops(l->bi, buffer); + IRCD->SendWallops(l->bi, buffer); } } } @@ -406,7 +406,7 @@ void LogInfo::ProcessMessage(const Log *l) { const Anope::string &target = this->targets[i]; - if (target.empty() || target[0] == '#' || target == "globops" || target.find(":") != Anope::string::npos) + if (target.empty() || target[0] == '#' || target == "opers" || target.find(":") != Anope::string::npos) continue; Anope::string oldlog = CreateLogName(target, Anope::CurTime - 86400 * this->log_age); diff --git a/src/protocol.cpp b/src/protocol.cpp index 5bf474a21..e299d1c2f 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -28,18 +28,15 @@ #include "channels.h" #include "numeric.h" -IRCDProto *IRCD = NULL; +IRCDProto *IRCD = nullptr; -IRCDProto::IRCDProto(Module *creator, const Anope::string &p) : Service(creator, "IRCDProto", creator->name), proto_name(p) +IRCDProto::IRCDProto(Module *creator, const Anope::string &p) : Service(creator, NAME, p) + , proto_name(p) { - if (IRCD == NULL) - IRCD = this; } IRCDProto::~IRCDProto() { - if (IRCD == this) - IRCD = NULL; } const Anope::string &IRCDProto::GetProtocolName() const @@ -47,119 +44,6 @@ const Anope::string &IRCDProto::GetProtocolName() const return this->proto_name; } -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 IRCDProto::UID_Retrieve() -{ - if (!IRCD || !IRCD->RequiresID) - return ""; - - static Anope::string current_uid = "AAAAAA"; - - do - { - int current_len = current_uid.length() - 1; - while (current_len >= 0 && nextID(current_len--, current_uid) == 'A'); - } - while (User::Find(Me->GetSID() + current_uid) != NULL); - - return Me->GetSID() + current_uid; -} - -Anope::string IRCDProto::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) != NULL); - - return current_sid; -} - -void IRCDProto::SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason) -{ - Uplink::Send(source, "KILL", target, reason); -} - -void IRCDProto::SendSVSKill(const MessageSource &source, User *user, const Anope::string &buf) -{ - Uplink::Send(source, "KILL", user->GetUID(), buf); -} - -void IRCDProto::SendMode(const MessageSource &source, Channel *dest, const Anope::string &buf) -{ - IRCMessage message(source, "MODE", dest->name); - message.TokenizeAndPush(buf); - Uplink::SendMessage(message); -} - -void IRCDProto::SendMode(const MessageSource &source, User *dest, const Anope::string &buf) -{ - IRCMessage message(source, "MODE", dest->GetUID()); - message.TokenizeAndPush(buf); - Uplink::SendMessage(message); -} - -void IRCDProto::SendKick(const MessageSource &source, Channel *c, User *u, const Anope::string &r) -{ - if (!r.empty()) - Uplink::Send(source, "KICK", c->name, u->GetUID(), r); - else - Uplink::Send(source, "KICK", c->name, u->GetUID()); -} - -void IRCDProto::SendNotice(const MessageSource &source, const Anope::string &dest, const Anope::string &msg) -{ - Uplink::Send(source, "NOTICE", dest, msg); -} - -void IRCDProto::SendPrivmsg(const MessageSource &source, const Anope::string &dest, const Anope::string &buf) -{ - Uplink::Send(source, "PRIVMSG", dest, buf); -} - -void IRCDProto::SendQuit(User *u, const Anope::string &buf) -{ - if (!buf.empty()) - Uplink::Send(u, "QUIT", buf); - else - Uplink::Send(u, "QUIT"); -} - -void IRCDProto::SendPart(User *u, Channel *chan, const Anope::string &buf) -{ - if (!buf.empty()) - Uplink::Send(u, "PART", chan->name, buf); - else - Uplink::Send(u, "PART", chan->name); -} - -void IRCDProto::SendGlobops(const MessageSource &source, const Anope::string &buf) -{ - Uplink::Send(source, "GLOBOPS", buf); -} - void IRCDProto::SendCTCPReply(const MessageSource &source, const Anope::string &dest, const Anope::string &buf) { Anope::string s = Anope::NormalizeBuffer(buf); @@ -171,11 +55,6 @@ void IRCDProto::SendNumeric(int numeric, User *dest, IRCMessage &message) Uplink::SendMessage(message); } -void IRCDProto::SendTopic(const MessageSource &source, Channel *c) -{ - Uplink::Send(source, "TOPIC", c->name, c->topic); -} - void IRCDProto::SendAction(const MessageSource &source, const Anope::string &dest, const Anope::string &message) { Anope::string actionbuf = "\1ACTION "; @@ -185,42 +64,6 @@ void IRCDProto::SendAction(const MessageSource &source, const Anope::string &des SendPrivmsg(source, dest, actionbuf); } -void IRCDProto::SendPing(const Anope::string &servname, const Anope::string &who) -{ - if (servname.empty()) - Uplink::Send(Me, "PING", who); - else - Uplink::Send(Me, "PING", servname, who); -} - -void IRCDProto::SendPong(const Anope::string &servname, const Anope::string &who) -{ - if (servname.empty()) - Uplink::Send(Me, "PONG", who); - else - Uplink::Send(Me, "PONG", servname, who); -} - -void IRCDProto::SendInvite(const MessageSource &source, Channel *c, User *u) -{ - Uplink::Send(source, "INVITE", u->GetUID(), c->name); -} - -void IRCDProto::SendSquit(Server *s, const Anope::string &message) -{ - Uplink::Send("SQUIT", s->GetSID(), message); -} - -void IRCDProto::SendNickChange(User *u, const Anope::string &newnick) -{ - Uplink::Send(u, "NICK", newnick, Anope::CurTime); -} - -void IRCDProto::SendForceNickChange(User *u, const Anope::string &newnick, time_t when) -{ - Uplink::Send(u, "SVSNICK", u->GetUID(), newnick, when); -} - bool IRCDProto::IsNickValid(const Anope::string &nick) { /** @@ -236,7 +79,7 @@ bool IRCDProto::IsNickValid(const Anope::string &nick) Anope::string special = "[]\\`_^{|}"; - for (unsigned i = 0; i < nick.length(); ++i) + for (unsigned int i = 0; i < nick.length(); ++i) if (!(nick[i] >= 'A' && nick[i] <= 'Z') && !(nick[i] >= 'a' && nick[i] <= 'z') && special.find(nick[i]) == Anope::string::npos && (Config && Config->NickChars.find(nick[i]) == Anope::string::npos) @@ -262,7 +105,7 @@ bool IRCDProto::IsIdentValid(const Anope::string &ident) if (ident.empty() || ident.length() > Config->GetBlock("networkinfo")->Get<unsigned>("userlen")) return false; - for (unsigned i = 0; i < ident.length(); ++i) + for (unsigned int i = 0; i < ident.length(); ++i) { const char &c = ident[i]; @@ -289,7 +132,7 @@ bool IRCDProto::IsHostValid(const Anope::string &host) return false; int dots = 0; - for (unsigned i = 0; i < host.length(); ++i) + for (unsigned int i = 0; i < host.length(); ++i) { if (host[i] == '.') ++dots; @@ -300,12 +143,6 @@ bool IRCDProto::IsHostValid(const Anope::string &host) return dots > 0 || Config->GetBlock("networkinfo")->Get<bool>("allow_undotted_vhosts"); } -void IRCDProto::SendOper(User *u) -{ - SendNumeric(RPL_YOUREOPER, u, "You are now an IRC operator (set by services)"); - u->SetMode(NULL, "OPER"); -} - unsigned int IRCDProto::GetMaxListFor(Channel *c) { return c->HasMode("LBAN") ? 0 : Config->GetBlock("networkinfo")->Get<int>("modelistsize"); @@ -376,7 +213,9 @@ Server *MessageSource::GetServer() const return this->s; } -IRCDMessage::IRCDMessage(Module *o, const Anope::string &n, unsigned int p) : Service(o, "IRCDMessage", o->name + "/" + n.lower()), name(n), param_count(p) +IRCDMessage::IRCDMessage(Module *o, const Anope::string &n, unsigned int p) : Service(o, NAME, o->name + "/" + n.lower()) + , name(n) + , param_count(p) { } diff --git a/src/servers.cpp b/src/servers.cpp index 5f48a5e7c..a04e36ded 100644 --- a/src/servers.cpp +++ b/src/servers.cpp @@ -81,7 +81,7 @@ Server::~Server() if (this->uplink) this->uplink->DelLink(this); - for (unsigned i = this->links.size(); i > 0; --i) + for (unsigned int i = this->links.size(); i > 0; --i) this->links[i - 1]->Delete(this->quit_reason); Servers::ByName.erase(this->name); @@ -101,12 +101,12 @@ void Server::Burst() { IRCD->SendBOB(); - for (unsigned i = 0; i < Me->GetLinks().size(); ++i) + for (unsigned int i = 0; i < Me->GetLinks().size(); ++i) { Server *s = Me->GetLinks()[i]; if (s->juped) - IRCD->SendServer(s); + IRCD->Send<messages::MessageServer>(s); } /* We make the bots go online */ @@ -117,11 +117,12 @@ void Server::Burst() ServiceBot *bi = ServiceBot::Find(u->GetUID()); if (bi) { +#warning "xline on stack" //XLine x(bi->nick, "Reserved for services"); //IRCD->SendSQLine(NULL, &x); } - IRCD->SendClientIntroduction(u); + IRCD->Send<messages::NickIntroduction>(u); if (bi) bi->introduced = true; } @@ -131,10 +132,10 @@ void Server::Burst() Channel *c = it->second; if (c->users.empty()) - IRCD->SendChannel(c); + IRCD->Send<messages::MessageChannel>(c); else for (Channel::ChanUserList::const_iterator cit = c->users.begin(), cit_end = c->users.end(); cit != cit_end; ++cit) - IRCD->SendJoin(cit->second->user, c, &cit->second->status); + IRCD->Send<messages::Join>(cit->second->user, c, &cit->second->status); for (Channel::ModeList::const_iterator it2 = c->GetModes().begin(); it2 != c->GetModes().end(); ++it2) { @@ -145,7 +146,7 @@ void Server::Burst() } if (!c->topic.empty() && !c->topic_setter.empty()) - IRCD->SendTopic(c->ci->WhoSends(), c); + IRCD->Send<messages::Topic>(c->ci->WhoSends(), c, c->topic, c->topic_ts, c->topic_setter); c->syncing = true; } @@ -308,9 +309,9 @@ bool Server::IsQuitting() const void Server::Notice(ServiceBot *source, const Anope::string &message) { if (Config->UsePrivmsg && Config->DefPrivmsg) - IRCD->SendGlobalPrivmsg(source, this, message); + IRCD->Send<messages::GlobalPrivmsg>(source, this, message); else - IRCD->SendGlobalNotice(source, this, message); + IRCD->Send<messages::GlobalNotice>(source, this, message); } Server *Server::Find(const Anope::string &name, bool name_only) diff --git a/src/service_manager.cpp b/src/service_manager.cpp index abebd1c3d..4c8d2a072 100644 --- a/src/service_manager.cpp +++ b/src/service_manager.cpp @@ -21,6 +21,7 @@ #include "services.h" #include "service.h" #include "logger.h" +#include "modules.h" ServiceManager *ServiceManager::manager = nullptr; @@ -79,7 +80,7 @@ void ServiceManager::Register(Service *service) Service *s = FindService(service->GetType(), service->GetName()); if (s != nullptr) - throw ModuleException("Service of type " + service->GetType() + " with name " + service->GetName() + " already exists"); + throw ModuleException("Service of type " + service->GetType() + " with name " + service->GetName() + " already exists from " + service->GetOwner()->name); } Log(LOG_DEBUG_3) << "Service registered: " << service->GetType() << " " << service->GetName() << " address " << static_cast<void *>(this) << " by " << service->GetOwner(); diff --git a/src/uplink.cpp b/src/uplink.cpp index c2b7579c5..1615eef9d 100644 --- a/src/uplink.cpp +++ b/src/uplink.cpp @@ -105,7 +105,7 @@ UplinkSocket::~UplinkSocket() } } - IRCD->SendSquit(Me, Anope::QuitReason); + IRCD->Send<messages::SQuit>(Me, Anope::QuitReason); this->ProcessWrite(); // Write out the last bit } @@ -155,7 +155,7 @@ bool UplinkSocket::ProcessRead() void UplinkSocket::OnConnect() { Log(LOG_TERMINAL) << "Successfully connected to uplink #" << (Anope::CurrentUplink + 1) << " " << Config->Uplinks[Anope::CurrentUplink].host << ":" << Config->Uplinks[Anope::CurrentUplink].port; - IRCD->SendConnect(); + IRCD->Handshake(); EventManager::Get()->Dispatch(&Event::ServerConnect::OnServerConnect); } diff --git a/src/users.cpp b/src/users.cpp index 33a4cdaf6..a9bb432b5 100644 --- a/src/users.cpp +++ b/src/users.cpp @@ -30,6 +30,7 @@ #include "sockets.h" #include "uplink.h" #include "event.h" +#include "messages.h" #include "modules/nickserv.h" user_map UserListByNick; @@ -105,7 +106,7 @@ static void CollideKill(User *target, const Anope::string &reason) static void Collide(User *u, const Anope::string &id, const Anope::string &type) { // Kill incoming user - IRCD->SendKill(Me, id, type); + IRCD->Send<messages::Kill>(Me, id, Me->GetName() + " (" + type + ")"); // Quit colliding user CollideKill(u, type); } @@ -383,7 +384,7 @@ void User::Identify(NickServ::Nick *na) na->SetLastSeen(Anope::CurTime); } - IRCD->SendLogin(this, na); + IRCD->Send<messages::Login>(this, na); this->Login(na->GetAccount()); @@ -397,15 +398,12 @@ void User::Identify(NickServ::Nick *na) { this->SetModes(NULL, "%s", m.c_str()); this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m.c_str()); - UserMode *um = ModeManager::FindUserModeByName("OPER"); - if (um && !this->HasMode("OPER") && m.find(um->mchar) != Anope::string::npos) - IRCD->SendOper(this); } if (IRCD->CanSetVHost && !oper->GetVhost().empty()) { this->SendMessage(Me, "Changing your vhost to \002{0}\002", oper->GetVhost()); this->SetDisplayedHost(oper->GetVhost()); - IRCD->SendVhost(this, "", oper->GetVhost()); + IRCD->Send<messages::VhostSet>(this, "", oper->GetVhost()); } } } @@ -571,15 +569,12 @@ void User::SetModeInternal(const MessageSource &source, UserMode *um, const Anop { this->SetModes(NULL, "%s", m.c_str()); this->SendMessage(Me, "Changing your usermodes to \002{0}\002", m); - UserMode *oper = ModeManager::FindUserModeByName("OPER"); - if (oper && !this->HasMode("OPER") && m.find(oper->mchar) != Anope::string::npos) - IRCD->SendOper(this); } if (IRCD->CanSetVHost && !oper->GetVhost().empty()) { this->SendMessage(Me, "Changing your vhost to \002{0}\002", oper->GetVhost()); this->SetDisplayedHost(oper->GetVhost()); - IRCD->SendVhost(this, "", oper->GetVhost()); + IRCD->Send<messages::VhostSet>(this, "", oper->GetVhost()); } } } @@ -769,7 +764,7 @@ void User::Kill(const MessageSource &source, const Anope::string &reason) { Anope::string real_reason = source.GetName() + " (" + reason + ")"; - IRCD->SendSVSKill(source, this, real_reason); + IRCD->SendKill(source, this, real_reason); } void User::KillInternal(const MessageSource &source, const Anope::string &reason) @@ -853,7 +848,7 @@ bool User::BadPassword() User* User::Find(const Anope::string &name, bool nick_only) { - if (!nick_only && IRCD->RequiresID) + if (!nick_only && IRCD && IRCD->RequiresID) { uid_map::iterator it = UserListByUID.find(name); if (it != UserListByUID.end()) |