summaryrefslogtreecommitdiff
path: root/include/protocol.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/protocol.h')
-rw-r--r--include/protocol.h395
1 files changed, 200 insertions, 195 deletions
diff --git a/include/protocol.h b/include/protocol.h
index 635399653..89186ccd1 100644
--- a/include/protocol.h
+++ b/include/protocol.h
@@ -1,200 +1,91 @@
/*
+ * Anope IRC Services
*
- * (C) 2003-2017 Anope Team
- * Contact us at team@anope.org
+ * Copyright (C) 2012-2017 Anope Team <team@anope.org>
*
- * Please read COPYING and README for further details.
+ * 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.
*
- * Based on the original code of Epona by Lara.
- * Based on the original code of Services by Andy Church.
+ * 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/>.
*/
-#ifndef PROTOCOL_H
-#define PROTOCOL_H
+#pragma once
#include "services.h"
#include "anope.h"
#include "service.h"
+#include "servers.h"
+#include "users.h"
+#include "messages.h"
+
+class IRCMessage;
/* Encapsultes the IRCd protocol we are speaking. */
class CoreExport IRCDProto : public Service
{
Anope::string proto_name;
- protected:
- IRCDProto(Module *creator, const Anope::string &proto_name);
- public:
- virtual ~IRCDProto();
-
- virtual void SendSVSKillInternal(const MessageSource &, User *, const Anope::string &);
- virtual void SendModeInternal(const MessageSource &, const Channel *, const Anope::string &);
- virtual void SendModeInternal(const MessageSource &, User *, const Anope::string &);
- virtual void SendKickInternal(const MessageSource &, const Channel *, User *, const Anope::string &);
- virtual void SendNoticeInternal(const MessageSource &, const Anope::string &dest, const Anope::string &msg);
- virtual void SendPrivmsgInternal(const MessageSource &, const Anope::string &dest, const Anope::string &buf);
- virtual void SendQuitInternal(User *, const Anope::string &buf);
- virtual void SendPartInternal(User *, const Channel *chan, const Anope::string &buf);
- virtual void SendGlobopsInternal(const MessageSource &, const Anope::string &buf);
- virtual void SendCTCPInternal(const MessageSource &, const Anope::string &dest, const Anope::string &buf);
- virtual void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf);
-
- const Anope::string &GetProtocolName();
- virtual void Parse(const Anope::string &, Anope::string &, Anope::string &, std::vector<Anope::string> &);
- virtual Anope::string Format(const Anope::string &source, const Anope::string &message);
+public:
+ static constexpr const char *NAME = "ircdproto";
/* Modes used by default by our clients */
- Anope::string DefaultPseudoclientModes;
+ Anope::string DefaultPseudoclientModes = "+io";
/* Can we force change a users's nick? */
- bool CanSVSNick;
+ bool CanSVSNick = false;
/* Can we force join or part users? */
- bool CanSVSJoin;
+ bool CanSVSJoin = false;
/* Can we set vhosts/vidents on users? */
- bool CanSetVHost, CanSetVIdent;
+ bool CanSetVHost = false, CanSetVIdent = false;
/* Can we ban specific gecos from being used? */
- bool CanSNLine;
+ bool CanSNLine = false;
/* Can we ban specific nicknames from being used? */
- bool CanSQLine;
+ bool CanSQLine = false;
/* Can we ban sepcific channel names from being used? */
- bool CanSQLineChannel;
+ bool CanSQLineChannel = false;
/* Can we ban by IP? */
- bool CanSZLine;
+ bool CanSZLine = false;
/* Can we place temporary holds on specific nicknames? */
- bool CanSVSHold;
- /* See os_oline */
- bool CanSVSO;
+ bool CanSVSHold = false;
/* See ns_cert */
- bool CanCertFP;
+ bool CanCertFP = false;
/* Whether this IRCd requires unique IDs for each user or server. See TS6/P10. */
- bool RequiresID;
+ bool RequiresID = false;
/* If this IRCd has unique ids, whether the IDs and nicknames are ambiguous */
- bool AmbiguousID;
+ bool AmbiguousID = false;
/* The maximum number of modes we are allowed to set with one MODE command */
- unsigned MaxModes;
+ unsigned int MaxModes = 3;
/* The maximum number of bytes a line may have */
- unsigned MaxLine;
-
- /* 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(const 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 *) = 0;
- virtual void SendAkillDel(const XLine *) = 0;
-
- /* Realname ban */
- virtual void SendSGLine(User *, const XLine *) { }
- virtual void SendSGLineDel(const XLine *) { }
-
- /* IP ban */
- virtual void SendSZLine(User *u, const XLine *) { }
- virtual void SendSZLineDel(const XLine *) { }
-
- /* Nick ban (and sometimes channel) */
- virtual void SendSQLine(User *, const XLine *x) { }
- virtual void SendSQLineDel(const XLine *x) { }
-
- virtual void SendKill(const MessageSource &source, const Anope::string &target, const Anope::string &reason);
-
- /** Kills a user
- * @param source Who is doing the kill
- * @param user The user to be killed
- * @param fmt Kill reason
- */
- virtual void SendSVSKill(const MessageSource &source, User *user, const char *fmt, ...);
+ unsigned int MaxLine = 512;
- virtual void SendMode(const MessageSource &source, const Channel *dest, const char *fmt, ...);
- virtual void SendMode(const MessageSource &source, User *u, const char *fmt, ...);
-
- /** Introduces a client to the rest of the network
- * @param u The client to introduce
- */
- virtual void SendClientIntroduction(User *u) = 0;
-
- virtual void SendKick(const MessageSource &source, const Channel *chan, User *user, const char *fmt, ...);
-
- virtual void SendNotice(const MessageSource &source, const Anope::string &dest, const char *fmt, ...);
- virtual void SendPrivmsg(const MessageSource &source, const Anope::string &dest, const char *fmt, ...);
- virtual void SendAction(const MessageSource &source, const Anope::string &dest, const char *fmt, ...);
- virtual void SendCTCP(const MessageSource &source, const Anope::string &dest, const char *fmt, ...);
-
- virtual void SendGlobalNotice(BotInfo *bi, const Server *dest, const Anope::string &msg) = 0;
- virtual void SendGlobalPrivmsg(BotInfo *bi, const Server *desc, const Anope::string &msg) = 0;
+ IRCDProto(Module *creator, const Anope::string &proto_name);
+ virtual ~IRCDProto();
- virtual void SendQuit(User *u, const char *fmt, ...);
- virtual void SendPing(const Anope::string &servname, const Anope::string &who);
- virtual void SendPong(const Anope::string &servname, const Anope::string &who);
+ const Anope::string &GetProtocolName() const;
- /** 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) = 0;
- virtual void SendPart(User *u, const Channel *chan, const char *fmt, ...);
-
- /** 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 &param) { }
-
- /** 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 &param) { }
+ virtual void Parse(const Anope::string &, Anope::string &, Anope::string &, std::vector<Anope::string> &);
+ virtual Anope::string Format(IRCMessage &);
- virtual void SendInvite(const MessageSource &source, const Channel *c, User *u);
- virtual void SendGlobops(const MessageSource &source, const char *fmt, ...);
+ virtual void SendCTCPReply(const MessageSource &, const Anope::string &dest, const Anope::string &buf);
+ virtual void SendNumeric(int numeric, User *dest, IRCMessage &);
- /** Sets oper flags on a user, currently only supported by Unreal
- */
- virtual void SendSVSO(BotInfo *, const Anope::string &, const Anope::string &) { }
+ /* Retrieves the next free UID or SID */
+ virtual Anope::string UID_Retrieve() { return ""; }
+ virtual Anope::string SID_Retrieve() { return ""; }
- /** 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);
+ virtual void SendAction(const MessageSource &source, const Anope::string &dest, const Anope::string &message);
- /** 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() = 0;
+ 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 servers, users, or channels exist on the uplink
@@ -202,35 +93,6 @@ class CoreExport IRCDProto : public Service
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(const Server *) = 0;
- virtual void SendSquit(Server *, const Anope::string &message);
-
- virtual void SendNumeric(int numeric, const Anope::string &dest, const char *fmt, ...);
-
- virtual void SendLogin(User *u, NickAlias *na) = 0;
- virtual void SendLogout(User *u) = 0;
-
- /** 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 &);
@@ -240,25 +102,98 @@ class CoreExport IRCDProto : public Service
/** Retrieve the maximum number of list modes settable on this channel
* Defaults to Config->ListSize
*/
- virtual unsigned GetMaxListFor(Channel *c);
+ virtual unsigned int GetMaxListFor(Channel *c);
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)
+ {
+ const char *const name = T::NAME;
+ Anope::Logger.Debug("No message sender for type {0}", 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 SendKill(const MessageSource &source, User *user, const Anope::string &reason, 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)
+ {
+ 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)
+ {
+ Send<messages::ModeUser>(source, u, Anope::Format(modes, std::forward<Args>(args)...));
+ }
+
+ template<typename... Args> void SendKick(const MessageSource &source, Channel *chan, User *user, const Anope::string &reason, 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)
+ {
+ 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)
+ {
+ 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)
+ {
+ SendAction(source, dest, Anope::Format(message, std::forward<Args>(args)...));
+ }
+
+ template<typename... Args> void SendCTCPReply(const MessageSource &source, const Anope::string &dest, const Anope::string &message, Args&&... args)
+ {
+ SendCTCPReply(source, dest, Anope::Format(message, std::forward<Args>(args)...));
+ }
+
+ template<typename... Args> void SendWallops(const MessageSource &source, const Anope::string &msg, 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)
+ {
+ 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)
+ {
+ Send<messages::Part>(u, chan, Anope::Format(reason, std::forward<Args>(args)...));
+ }
};
class CoreExport MessageSource
{
Anope::string source;
- User *u;
- Server *s;
+ User *u = nullptr;
+ Server *s = nullptr;
public:
MessageSource(const Anope::string &);
MessageSource(User *u);
MessageSource(Server *s);
const Anope::string &GetName() const;
+ const Anope::string &GetUID() const;
const Anope::string &GetSource() const;
User *GetUser() const;
- BotInfo *GetBot() const;
+ ServiceBot *GetBot() const;
Server *GetServer() const;
};
@@ -272,12 +207,14 @@ enum IRCDMessageFlag
class CoreExport IRCDMessage : public Service
{
Anope::string name;
- unsigned param_count;
+ unsigned int param_count;
std::set<IRCDMessageFlag> flags;
public:
- IRCDMessage(Module *owner, const Anope::string &n, unsigned p = 0);
- unsigned GetParamCount() const;
- virtual void Run(MessageSource &, const std::vector<Anope::string> &params) = 0;
+ static constexpr const char *NAME = "ircdmessage";
+
+ IRCDMessage(Module *owner, const Anope::string &n, unsigned int p = 0);
+ unsigned int GetParamCount() const;
+ virtual void Run(MessageSource &, const std::vector<Anope::string> &params) anope_abstract;
void SetFlag(IRCDMessageFlag f) { flags.insert(f); }
bool HasFlag(IRCDMessageFlag f) const { return flags.count(f); }
@@ -285,4 +222,72 @@ class CoreExport IRCDMessage : public Service
extern CoreExport IRCDProto *IRCD;
-#endif // PROTOCOL_H
+class IRCMessage
+{
+ MessageSource source;
+ Anope::string command;
+ std::vector<Anope::string> parameters;
+
+ public:
+ template<typename... Args>
+ IRCMessage(const MessageSource &_source, const Anope::string &_command, Args&&... args)
+ : source(_source)
+ , command(_command)
+ {
+ parameters.reserve(sizeof...(args));
+
+ Push(std::forward<Args>(args)...);
+ }
+
+ template<typename T, typename... Args>
+ void Push(const T& t, Args&&... args)
+ {
+ parameters.push_back(stringify(t));
+
+ Push(std::forward<Args>(args)...);
+ }
+
+ void Push() { }
+
+ void TokenizeAndPush(const Anope::string &buf, char sepToken = ' ')
+ {
+ sepstream sep(buf, sepToken);
+ Anope::string token;
+ while (sep.GetToken(token))
+ Push(token);
+ }
+
+ const MessageSource &GetSource() const
+ {
+ return source;
+ }
+
+ void SetSource(const MessageSource &_source)
+ {
+ this->source = _source;
+ }
+
+ const Anope::string &GetCommand() const
+ {
+ return command;
+ }
+
+ const std::vector<Anope::string> &GetParameters() const
+ {
+ return parameters;
+ }
+};
+
+template<typename... Args>
+void IRCDProto::SendNumeric(int numeric, User *dest, Args&&... args)
+{
+ Anope::string numstr = stringify(numeric);
+ if (numeric < 10)
+ numstr.insert(numstr.begin(), '0');
+ if (numeric < 100)
+ numstr.insert(numstr.begin(), '0');
+
+ IRCMessage message(Me, numstr, dest->GetUID());
+ message.Push(std::forward<Args>(args)...);
+ SendNumeric(numeric, dest, message);
+}