From 89428a9d1032e3c2a6e397629a32862b3e58d708 Mon Sep 17 00:00:00 2001 From: Adam Date: Mon, 1 Oct 2012 01:56:57 -0400 Subject: Cleanup of all of the protocol modules, rewrote message handling system to be a bit more C++ ish --- include/anope.h | 6 - include/channels.h | 17 +- include/defs.h | 1 + include/extern.h | 28 -- include/messages.h | 119 ++++++ include/module.h | 1 + include/modules.h | 25 +- include/protocol.h | 130 +++--- include/servers.h | 8 +- include/users.h | 24 +- modules/commands/bs_bot.cpp | 7 +- modules/commands/cs_seen.cpp | 4 +- modules/commands/hs_on.cpp | 12 +- modules/commands/hs_request.cpp | 5 +- modules/commands/hs_set.cpp | 4 +- modules/commands/ns_cert.cpp | 2 +- modules/commands/ns_info.cpp | 2 +- modules/commands/os_defcon.cpp | 12 +- modules/commands/os_forbid.cpp | 2 +- modules/commands/os_jupe.cpp | 2 +- modules/commands/os_oline.cpp | 2 +- modules/commands/os_stats.cpp | 4 +- modules/commands/os_svsnick.cpp | 2 +- modules/commands/os_sxline.cpp | 21 +- modules/extra/m_chanstats.cpp | 17 +- modules/extra/m_proxyscan.cpp | 2 +- modules/extra/webcpanel/webcpanel.cpp | 2 +- modules/protocol/bahamut.cpp | 322 +++++++------- modules/protocol/inspircd-ts6.h | 386 +++++++++++++---- modules/protocol/inspircd11.cpp | 571 ++++++++++++------------- modules/protocol/inspircd12.cpp | 389 ++++------------- modules/protocol/inspircd20.cpp | 399 +++++------------ modules/protocol/plexus.cpp | 538 +++++++++++++---------- modules/protocol/ratbox.cpp | 445 ++++++++++--------- modules/protocol/unreal.cpp | 783 ++++++++++++++++------------------ modules/pseudoclients/botserv.cpp | 2 +- modules/pseudoclients/hostserv.cpp | 17 +- modules/pseudoclients/operserv.cpp | 4 +- src/bots.cpp | 7 +- src/botserv.cpp | 2 +- src/channels.cpp | 249 +++-------- src/init.cpp | 2 - src/main.cpp | 10 +- src/messages.cpp | 393 +++++++++++++---- src/modes.cpp | 4 +- src/modules.cpp | 52 --- src/nickalias.cpp | 9 +- src/nickserv.cpp | 11 +- src/process.cpp | 28 +- src/protocol.cpp | 297 +++---------- src/servers.cpp | 57 +-- src/users.cpp | 224 ++++------ 52 files changed, 2664 insertions(+), 2998 deletions(-) create mode 100644 include/messages.h diff --git a/include/anope.h b/include/anope.h index e67fafc8d..3c13d68ab 100644 --- a/include/anope.h +++ b/include/anope.h @@ -324,12 +324,6 @@ namespace Anope */ extern CoreExport bool Match(const string &str, const string &mask, bool case_sensitive = false, bool use_regex = false); - /** Find a message in the message table - * @param name The name of the message were looking for - * @return NULL if we cant find it, or a pointer to the Message if we can - */ - extern CoreExport std::vector FindMessage(const string &name); - /** Converts a string to hex * @param the data to be converted * @return a anope::string containing the hex value diff --git a/include/channels.h b/include/channels.h index b64ae84f4..7dee744c2 100644 --- a/include/channels.h +++ b/include/channels.h @@ -140,7 +140,7 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< * @param param The param * @param EnforceMLock true if mlocks should be enforced, false to override mlock */ - void SetModeInternal(User *setter, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); + void SetModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); /** Remove a mode internally on a channel, this is not sent out to the IRCd * @param setter The Setter @@ -148,7 +148,7 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< * @param param The param * @param EnforceMLock true if mlocks should be enforced, false to override mlock */ - void RemoveModeInternal(User *setter, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); + void RemoveModeInternal(MessageSource &source, ChannelMode *cm, const Anope::string ¶m = "", bool EnforceMLock = true); /** Set a mode on a channel * @param bi The client setting the modes @@ -199,18 +199,18 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< void SetModes(BotInfo *bi, bool EnforceMLock, const char *cmodes, ...); /** Set a string of modes internally on a channel - * @param setter the setter (if it is a user) + * @param source The setter * @param mode the modes * @param EnforceMLock true to enforce mlock */ - void SetModesInternal(User *setter, const Anope::string &mode, bool EnforceMLock = true); + void SetModesInternal(MessageSource &source, const Anope::string &mode, time_t ts = Anope::CurTime, bool EnforceMLock = true); /** Kick a user from a channel internally * @param source The sender of the kick * @param nick The nick being kicked * @param reason The reason for the kick */ - void KickInternal(const Anope::string &source, const Anope::string &nick, const Anope::string &reason); + void KickInternal(MessageSource &source, const Anope::string &nick, const Anope::string &reason); /** Kick a user from the channel * @param bi The sender, can be NULL for the service bot for this channel @@ -228,7 +228,7 @@ class CoreExport Channel : public virtual Base, public Extensible, public Flags< Anope::string GetModes(bool complete, bool plus); /** Update the topic of the channel internally, and reset it if topiclock etc says to - * @param user THe user setting the new topic + * @param user The user setting the new topic * @param newtopic The new topic * @param ts The time the new topic is being set */ @@ -250,11 +250,6 @@ extern CoreExport Channel *findchan(const Anope::string &chan); extern CoreExport User *nc_on_chan(Channel *c, const NickCore *nc); -extern CoreExport void do_cmode(const Anope::string &source, const Anope::string &channel, const Anope::string &modes, const Anope::string &ts); -extern CoreExport void do_join(const Anope::string &source, const Anope::string &channels, const Anope::string &ts); -extern CoreExport void do_kick(const Anope::string &source, const Anope::string &channel, const Anope::string &users, const Anope::string &reason); -extern CoreExport void do_part(const Anope::string &source, const Anope::string &channels, const Anope::string &reason); - extern CoreExport void chan_set_correct_modes(const User *user, Channel *c, int give_modes, bool check_noop); #endif // CHANNELS_H diff --git a/include/defs.h b/include/defs.h index 2df0a2c15..d58f7fed6 100644 --- a/include/defs.h +++ b/include/defs.h @@ -49,6 +49,7 @@ struct BadWord; struct DNSQuery; struct Exception; struct MemoInfo; +struct MessageSource; struct ModeLock; struct Oper; diff --git a/include/extern.h b/include/extern.h index 5eb7dcb58..e8a47c209 100644 --- a/include/extern.h +++ b/include/extern.h @@ -71,34 +71,6 @@ E int CurrentUplink; E void save_databases(); E void sighandler(int signum); -/**** messages.cpp ****/ - -E void init_core_messages(); - -E bool OnStats(const Anope::string &source, const std::vector &); -E bool OnTime(const Anope::string &source, const std::vector &); -E bool OnVersion(const Anope::string &source, const std::vector &); - -E bool On436(const Anope::string &, const std::vector &); -E bool OnAway(const Anope::string &, const std::vector &); -E bool OnJoin(const Anope::string &, const std::vector &); -E bool OnKick(const Anope::string &, const std::vector &); -E bool OnKill(const Anope::string &, const std::vector &); -E bool OnMode(const Anope::string &, const std::vector &); -E bool OnNick(const Anope::string &, const std::vector &); -E bool OnUID(const Anope::string &, const std::vector &); -E bool OnPart(const Anope::string &, const std::vector &); -E bool OnPing(const Anope::string &, const std::vector &); -E bool OnPrivmsg(const Anope::string &, const std::vector &); -E bool OnQuit(const Anope::string &, const std::vector &); -E bool OnServer(const Anope::string &, const std::vector &); -E bool OnSQuit(const Anope::string &, const std::vector &); -E bool OnTopic(const Anope::string &, const std::vector &); -E bool OnWhois(const Anope::string &, const std::vector &); -E bool OnCapab(const Anope::string &, const std::vector &); -E bool OnSJoin(const Anope::string &, const std::vector &); -E bool OnError(const Anope::string &, const std::vector &); - /**** misc.c ****/ E bool IsFile(const Anope::string &filename); diff --git a/include/messages.h b/include/messages.h new file mode 100644 index 000000000..115f659af --- /dev/null +++ b/include/messages.h @@ -0,0 +1,119 @@ +#include "protocol.h" + +/* Common IRCD messages. + * Protocol modules may chose to include some, none, or all of these handlers + * as they see fit. + */ + +struct CoreIRCDMessageAway : IRCDMessage +{ + CoreIRCDMessageAway(const Anope::string &mname = "AWAY") : IRCDMessage(mname, 0) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageCapab : IRCDMessage +{ + CoreIRCDMessageCapab(const Anope::string &mname = "CAPAB") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageError : IRCDMessage +{ + CoreIRCDMessageError(const Anope::string &mname = "ERROR") : IRCDMessage(mname, 1) { } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageJoin : IRCDMessage +{ + CoreIRCDMessageJoin(const Anope::string &mname = "JOIN") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageKill : IRCDMessage +{ + CoreIRCDMessageKill(const Anope::string &mname = "KILL") : IRCDMessage(mname, 2) { } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageMOTD : IRCDMessage +{ + CoreIRCDMessageMOTD(const Anope::string &mname = "MOTD") : IRCDMessage(mname, 1) { } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessagePart : IRCDMessage +{ + CoreIRCDMessagePart(const Anope::string &mname = "PART") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessagePing : IRCDMessage +{ + CoreIRCDMessagePing(const Anope::string &mname = "PING") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessagePrivmsg : IRCDMessage +{ + CoreIRCDMessagePrivmsg(const Anope::string &mname = "PRIVMSG") : IRCDMessage(mname, 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageQuit : IRCDMessage +{ + CoreIRCDMessageQuit(const Anope::string &mname = "QUIT") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageSQuit : IRCDMessage +{ + CoreIRCDMessageSQuit(const Anope::string &mname = "SQUIT") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageStats : IRCDMessage +{ + CoreIRCDMessageStats(const Anope::string &mname = "STATS") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageTime : IRCDMessage +{ + CoreIRCDMessageTime(const Anope::string &mname = "TIME") : IRCDMessage(mname, 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageTopic : IRCDMessage +{ + CoreIRCDMessageTopic(const Anope::string &mname = "TOPIC") : IRCDMessage(mname, 2) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageVersion : IRCDMessage +{ + CoreIRCDMessageVersion(const Anope::string &mname = "VERSION") : IRCDMessage(mname, 0) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + +struct CoreIRCDMessageWhois : IRCDMessage +{ + CoreIRCDMessageWhois(const Anope::string &mname = "WHOIS") : IRCDMessage(mname, 1) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override; +}; + diff --git a/include/module.h b/include/module.h index 6865a2c17..bba901741 100644 --- a/include/module.h +++ b/include/module.h @@ -31,6 +31,7 @@ #include "logger.h" #include "mail.h" #include "memo.h" +#include "messages.h" #include "modes.h" #include "modules.h" #include "oper.h" diff --git a/include/modules.h b/include/modules.h index 939b98b34..9d3d701e3 100644 --- a/include/modules.h +++ b/include/modules.h @@ -141,9 +141,6 @@ enum Priority { PRIORITY_FIRST, PRIORITY_DONTCARE, PRIORITY_LAST, PRIORITY_BEFOR /* Module types, in the order in which they are unloaded. The order these are in is IMPORTANT */ enum ModType { MT_BEGIN, THIRD, SUPPORTED, CORE, DATABASE, ENCRYPTION, PROTOCOL, MT_END }; -typedef std::multimap message_map; -extern CoreExport message_map MessageMap; - extern CoreExport std::list Modules; class ModuleVersion @@ -268,7 +265,7 @@ class CoreExport Module : public Extensible * @param source The nick of the sender. * @param kickmsg The reason for the kick. */ - virtual void OnUserKicked(Channel *c, User *target, const Anope::string &source, const Anope::string &kickmsg) { } + virtual void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &kickmsg) { } /** Called when Services' configuration has been loaded. */ @@ -439,7 +436,7 @@ class CoreExport Module : public Extensible * @param setter The user who set the new topic * @param topic The new topic */ - virtual void OnTopicUpdated(Channel *c, User *setter, const Anope::string &topic) { } + virtual void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) { } /** Called before a channel expires * @param ci The channel @@ -828,21 +825,21 @@ class CoreExport Module : public Extensible /** Called when a mode is set on a channel * @param c The channel - * @param setter The user who is setting the mode + * @param setter The user or server that is setting the mode * @param Name The mode name * @param param The mode param, if there is one * @return EVENT_STOP to make mlock/secureops etc checks not happen */ - virtual EventReturn OnChannelModeSet(Channel *c, User *setter, ChannelModeName Name, const Anope::string ¶m) { return EVENT_CONTINUE; } + virtual EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) { return EVENT_CONTINUE; } /** Called when a mode is unset on a channel * @param c The channel - * @param setter the user who is unsetting the mode + * @param setter The user or server that is unsetting the mode * @param Name The mode name * @param param The mode param, if there is one * @return EVENT_STOP to make mlock/secureops etc checks not happen */ - virtual EventReturn OnChannelModeUnset(Channel *c, User *setter, ChannelModeName Name, const Anope::string ¶m) { return EVENT_CONTINUE; } + virtual EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) { return EVENT_CONTINUE; } /** Called when a mode is set on a user * @param u The user @@ -1121,14 +1118,4 @@ class CoreExport CallBack : public Timer virtual ~CallBack(); }; -class CoreExport Message -{ -public: - Anope::string name; - bool (*func)(const Anope::string &source, const std::vector ¶ms); - - Message(const Anope::string &n, bool (*f)(const Anope::string &, const std::vector &)); - ~Message(); -}; - #endif // MODULES_H diff --git a/include/protocol.h b/include/protocol.h index 5fb9da403..d4ff79082 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -17,39 +17,15 @@ #include "services.h" #include "anope.h" -/* Protocol tweaks */ - -struct IRCDVar -{ - const char *name; /* Name of the IRCd command */ - const char *pseudoclient_mode; /* Mode used by BotServ Bots */ - int svsnick; /* Supports SVSNICK */ - int vhost; /* Supports vhost */ - int snline; /* Supports SNline */ - int sqline; /* Supports SQline */ - int szline; /* Supports SZline */ - int join2msg; /* Join 2 Message */ - int chansqline; /* Supports Channel Sqlines */ - int quitonkill; /* IRCD sends QUIT when kill */ - int vident; /* Supports vidents */ - int svshold; /* Supports svshold */ - int tsonmode; /* Timestamp on mode changes */ - int omode; /* On the fly o:lines */ - int umode; /* change user modes */ - int knock_needs_i; /* Check if we needed +i when setting NOKNOCK */ - int svsmode_ucmode; /* Can remove User Channel Modes with SVSMODE */ - int sglineenforce; - int ts6; /* ircd is TS6 */ - const char *globaltldprefix; /* TLD prefix used for Global */ - unsigned maxmodes; /* Max modes to send per line */ - int certfp; /* IRCd sends a SSL users certificate fingerprint */ -}; - - class CoreExport IRCDProto { + Anope::string proto_name; + + IRCDProto() { } protected: - virtual void SendSVSKillInternal(const BotInfo *, const User *, const Anope::string &); + IRCDProto(const Anope::string &proto_name); + + virtual void SendSVSKillInternal(const BotInfo *, User *, const Anope::string &); virtual void SendModeInternal(const BotInfo *, const Channel *, const Anope::string &); virtual void SendModeInternal(const BotInfo *, const User *, const Anope::string &) = 0; virtual void SendKickInternal(const BotInfo *, const Channel *, const User *, const Anope::string &); @@ -62,14 +38,40 @@ class CoreExport IRCDProto virtual void SendCTCPInternal(const BotInfo *bi, const Anope::string &dest, const Anope::string &buf); virtual void SendNumericInternal(int numeric, const Anope::string &dest, const Anope::string &buf); public: - virtual ~IRCDProto() { } + virtual ~IRCDProto(); + + const Anope::string &GetProtocolName(); + /* Modes used by default by our clients */ + Anope::string DefaultPseudoclientModes; + /* Can we force change a users's nick */ + bool CanSVSNick; + /* Can we set vhosts/vidents on users? */ + bool CanSetVHost, CanSetVIdent; + /* Can we ban specific gecos from being used? */ + bool CanSNLine; + /* Can we ban specific nicknames from being used? */ + bool CanSQLine; + /* Can we ban sepcific channel names from being used? */ + bool CanSQLineChannel; + /* Can we ban by IP? */ + bool CanSZLine; + /* Can we place temporary holds on specific nicknames? */ + bool CanSVSHold; + /* See os_oline */ + bool CanSVSO; + /* See ns_cert */ + bool CanCertFP; + /* Whether this IRCd requires unique IDs for each user or server. See TS6/P10. */ + bool RequiresID; + /* The maximum number of modes we are allowed to set with one MODE command */ + unsigned MaxModes; virtual void SendSVSNOOP(const Server *, bool) { } virtual void SendTopic(BotInfo *, Channel *); virtual void SendVhostDel(User *) { } virtual void SendAkill(User *, XLine *) = 0; virtual void SendAkillDel(const XLine *) = 0; - virtual void SendSVSKill(const BotInfo *source, const User *user, const char *fmt, ...); + virtual void SendSVSKill(const BotInfo *source, User *user, const char *fmt, ...); virtual void SendMode(const BotInfo *bi, const Channel *dest, const char *fmt, ...); virtual void SendMode(const BotInfo *bi, const User *u, const char *fmt, ...); virtual void SendClientIntroduction(const User *u) = 0; @@ -78,8 +80,8 @@ class CoreExport IRCDProto virtual void SendNotice(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...); virtual void SendAction(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...); virtual void SendPrivmsg(const BotInfo *bi, const Anope::string &dest, const char *fmt, ...); - virtual void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg); - virtual void SendGlobalPrivmsg(const BotInfo *bi, const Server *desc, const Anope::string &msg); + virtual void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) = 0; + virtual void SendGlobalPrivmsg(const BotInfo *bi, const Server *desc, const Anope::string &msg) = 0; virtual void SendQuit(const User *u, const char *fmt, ...); virtual void SendPing(const Anope::string &servname, const Anope::string &who); @@ -120,36 +122,44 @@ class CoreExport IRCDProto virtual void SendChannel(Channel *c) { } }; -class CoreExport IRCdMessage +enum IRCDMessageFlag { + IRCDMESSAGE_SOFT_LIMIT, + IRCDMESSAGE_REQUIRE_SERVER, + IRCDMESSAGE_REQUIRE_USER +}; + +class CoreExport MessageSource +{ + Anope::string source; + User *u; + Server *s; + public: - virtual bool On436(const Anope::string &, const std::vector &); - virtual bool OnAway(const Anope::string &, const std::vector &); - virtual bool OnJoin(const Anope::string &, const std::vector &); - virtual bool OnKick(const Anope::string &, const std::vector &); - virtual bool OnKill(const Anope::string &, const std::vector &); - virtual bool OnMode(const Anope::string &, const std::vector &) = 0; - virtual bool OnUID(const Anope::string &, const std::vector &); - virtual bool OnNick(const Anope::string &, const std::vector &) = 0; - virtual bool OnPart(const Anope::string &, const std::vector &); - virtual bool OnPing(const Anope::string &, const std::vector &); - virtual bool OnPrivmsg(const Anope::string &, const std::vector &); - virtual bool OnQuit(const Anope::string &, const std::vector &); - virtual bool OnServer(const Anope::string &, const std::vector &) = 0; - virtual bool OnSQuit(const Anope::string &, const std::vector &); - virtual bool OnTopic(const Anope::string &, const std::vector &) = 0; - virtual bool OnWhois(const Anope::string &, const std::vector &); - virtual bool OnCapab(const Anope::string &, const std::vector &); - virtual bool OnSJoin(const Anope::string &, const std::vector &) = 0; - virtual bool OnError(const Anope::string &, const std::vector &); + MessageSource(const Anope::string &); + MessageSource(User *u); + MessageSource(Server *s); + const Anope::string GetName(); + const Anope::string &GetSource(); + User *GetUser(); + Server *GetServer(); }; -extern CoreExport IRCDVar *ircd; -extern CoreExport IRCDProto *ircdproto; -extern CoreExport IRCdMessage *ircdmessage; +class CoreExport IRCDMessage : public Flags +{ + static std::map > messages; -extern CoreExport void pmodule_ircd_proto(IRCDProto *); -extern CoreExport void pmodule_ircd_var(IRCDVar *ircdvar); -extern CoreExport void pmodule_ircd_message(IRCdMessage *message); + Anope::string name; + unsigned param_count; + public: + static const std::vector *Find(const Anope::string &name); + + IRCDMessage(const Anope::string &n, unsigned p = 0); + ~IRCDMessage(); + unsigned GetParamCount() const; + virtual bool Run(MessageSource &, const std::vector ¶ms) = 0; +}; + +extern CoreExport IRCDProto *ircdproto; #endif // PROTOCOL_H diff --git a/include/servers.h b/include/servers.h index 7b85a182a..94dc5491e 100644 --- a/include/servers.h +++ b/include/servers.h @@ -7,8 +7,6 @@ /* Anope */ extern CoreExport Server *Me; -extern CoreExport void do_server(const Anope::string &source, const Anope::string &servername, unsigned int hops, const Anope::string &descript, const Anope::string &numeric); - extern CoreExport const Anope::string ts6_uid_retrieve(); extern CoreExport const Anope::string ts6_sid_retrieve(); @@ -57,12 +55,14 @@ class CoreExport Server : public Flags * @param sid Server sid/numeric * @param flag An optional server flag */ - Server(Server *uplink, const Anope::string &name, unsigned hops, const Anope::string &description, const Anope::string &sid, ServerFlag flag = SERVER_NONE); + Server(Server *uplink, const Anope::string &name, unsigned hops, const Anope::string &description, const Anope::string &sid = "", ServerFlag flag = SERVER_NONE); + private: /** Destructor */ ~Server(); + public: /** Delete this server with a reason * @param reason The reason */ @@ -93,7 +93,7 @@ class CoreExport Server : public Flags */ void SetSID(const Anope::string &sid); - /** Get the server numeric/SID + /** Get the server numeric/SID, else the server name * @return The numeric/SID */ const Anope::string &GetSID() const; diff --git a/include/users.h b/include/users.h index fab5fa868..502cc0a7c 100644 --- a/include/users.h +++ b/include/users.h @@ -82,9 +82,15 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe * @param snick The nickname of the user. * @param sident The username of the user * @param shost The hostname of the user + * @param svhost The vhost of the user + * @param sip The ip of the user + * @param sserver The server of the user + * @param srealname The realname/gecos of teh user + * @param ssignon User's timestamp + * @param smodes User's modes * @param suid The unique identifier of the user. */ - User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &suid = ""); + User(const Anope::string &snick, const Anope::string &sident, const Anope::string &shost, const Anope::string &svhost, const Anope::string &sip, Server *sserver, const Anope::string &srealname, time_t ssignon, const Anope::string &smodes, const Anope::string &suid = ""); /** Destroy a user. */ @@ -93,7 +99,7 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe /** Update the nickname of a user record accordingly, should be * called from ircd protocol. */ - void SetNewNick(const Anope::string &newnick); + void ChangeNick(const Anope::string &newnick); /** Update the displayed (vhost) of a user record. * This is used (if set) instead of real host. @@ -116,8 +122,7 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe */ const Anope::string &GetCloakedHost() const; - /** Retrieves the UID of the user, where applicable, if set. - * This is not used on some IRCds, but is for a lot e.g. P10, TS6 protocols. + /** Retrieves the UID of the user, if set, else the nick. * @return The UID of the user. */ const Anope::string &GetUID() const; @@ -302,6 +307,12 @@ class CoreExport User : public virtual Base, public Extensible, public CommandRe * @param reason The reason for the kill */ void Kill(const Anope::string &source, const Anope::string &reason); + + /** Process a kill for a user + * @param source The user/server doing the kill + * @param reason The reason for the kill + */ + void KillInternal(const Anope::string &source, const Anope::string &reason); }; extern CoreExport int32_t opcnt; @@ -310,11 +321,6 @@ extern CoreExport time_t maxusertime; extern CoreExport User *finduser(const Anope::string &nick); -extern CoreExport User *do_nick(const Anope::string &source, const Anope::string &nick, const Anope::string &username, const Anope::string &host, const Anope::string &server, const Anope::string &realname, time_t ts, const Anope::string &ip, const Anope::string &vhost, const Anope::string &uid, const Anope::string &modes); - -extern CoreExport void do_umode(const Anope::string &user, const Anope::string &modes); -extern CoreExport void do_kill(User *user, const Anope::string &reason); - extern CoreExport bool matches_list(Channel *c, User *user, ChannelModeName mode); extern CoreExport Anope::string create_mask(User *u); diff --git a/modules/commands/bs_bot.cpp b/modules/commands/bs_bot.cpp index 0b45ee71c..de7fa1128 100644 --- a/modules/commands/bs_bot.cpp +++ b/modules/commands/bs_bot.cpp @@ -218,11 +218,8 @@ class CommandBSBot : public Command } /* The new nick is really different, so we remove the Q line for the old nick. */ - if (ircd->sqline) - { - XLine x(bi->nick); - ircdproto->SendSQLineDel(&x); - } + XLine x_del(bi->nick); + ircdproto->SendSQLineDel(&x_del); /* Add a Q line for the new nick */ XLine x(nick, "Reserved for services"); diff --git a/modules/commands/cs_seen.cpp b/modules/commands/cs_seen.cpp index 289988867..ce88efa44 100644 --- a/modules/commands/cs_seen.cpp +++ b/modules/commands/cs_seen.cpp @@ -376,9 +376,9 @@ class CSSeen : public Module UpdateUser(u, PART, u->nick, "", channel, msg); } - void OnUserKicked(Channel *c, User *target, const Anope::string &source, const Anope::string &msg) anope_override + void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &msg) anope_override { - UpdateUser(target, KICK, target->nick, source, c->name, msg); + UpdateUser(target, KICK, target->nick, source.GetSource(), c->name, msg); } private: diff --git a/modules/commands/hs_on.cpp b/modules/commands/hs_on.cpp index 91fcaf10e..d02dd7dfe 100644 --- a/modules/commands/hs_on.cpp +++ b/modules/commands/hs_on.cpp @@ -27,6 +27,8 @@ class CommandHSOn : public Command User *u = source.GetUser(); if (!u) return; + else if (!ircdproto->CanSetVHost) + return; // HostServ wouldn't even be loaded at this point const NickAlias *na = findnick(u->nick); if (na && u->Account() == na->nc && na->HasVhost()) @@ -37,13 +39,9 @@ class CommandHSOn : public Command source.Reply(_("Your vhost of \002%s\002 is now activated."), na->GetVhostHost().c_str()); Log(LOG_COMMAND, source, this) << "to enable their vhost of " << (!na->GetVhostIdent().empty() ? na->GetVhostIdent() + "@" : "") << na->GetVhostHost(); ircdproto->SendVhost(u, na->GetVhostIdent(), na->GetVhostHost()); - if (ircd->vhost) - u->vhost = na->GetVhostHost(); - if (ircd->vident) - { - if (!na->GetVhostIdent().empty()) - u->SetVIdent(na->GetVhostIdent()); - } + u->vhost = na->GetVhostHost(); + if (ircdproto->CanSetVIdent && !na->GetVhostIdent().empty()) + u->SetVIdent(na->GetVhostIdent()); u->UpdateHost(); } else diff --git a/modules/commands/hs_request.cpp b/modules/commands/hs_request.cpp index f4b710b7f..94b181f51 100644 --- a/modules/commands/hs_request.cpp +++ b/modules/commands/hs_request.cpp @@ -121,7 +121,7 @@ class CommandHSRequest : public Command source.Reply(HOST_SET_IDENTTOOLONG, Config->UserLen); return; } - else if (!ircd->vident) + else if (!ircdproto->CanSetVIdent) { source.Reply(HOST_NO_VIDENT); return; @@ -354,6 +354,9 @@ class HSRequest : public Module { this->SetAuthor("Anope"); + if (!ircdproto || !ircdproto->CanSetVHost) + throw ModuleException("Your IRCd does not support vhosts"); + Implementation i[] = { I_OnReload }; ModuleManager::Attach(i, this, sizeof(i) / sizeof(Implementation)); diff --git a/modules/commands/hs_set.cpp b/modules/commands/hs_set.cpp index b2509bcea..2189f2483 100644 --- a/modules/commands/hs_set.cpp +++ b/modules/commands/hs_set.cpp @@ -55,7 +55,7 @@ class CommandHSSet : public Command if (!user.empty()) { - if (!ircd->vident) + if (!ircdproto->CanSetVIdent) { source.Reply(HOST_NO_VIDENT); return; @@ -156,7 +156,7 @@ class CommandHSSetAll : public Command if (!user.empty()) { - if (!ircd->vident) + if (!ircdproto->CanSetVIdent) { source.Reply(HOST_NO_VIDENT); return; diff --git a/modules/commands/ns_cert.cpp b/modules/commands/ns_cert.cpp index da3cb2aa1..a06dd1a3a 100644 --- a/modules/commands/ns_cert.cpp +++ b/modules/commands/ns_cert.cpp @@ -225,7 +225,7 @@ class NSCert : public Module { this->SetAuthor("Anope"); - if (!ircd || !ircd->certfp) + if (!ircdproto || !ircdproto->CanCertFP) throw ModuleException("Your IRCd does not support ssl client certificates"); Implementation i[] = { I_OnFingerprint }; diff --git a/modules/commands/ns_info.cpp b/modules/commands/ns_info.cpp index b3b734a39..5daf2357e 100644 --- a/modules/commands/ns_info.cpp +++ b/modules/commands/ns_info.cpp @@ -102,7 +102,7 @@ class CommandNSInfo : public Command { if (na->HasVhost()) { - if (ircd->vident && !na->GetVhostIdent().empty()) + if (ircdproto->CanSetVIdent && !na->GetVhostIdent().empty()) info[_("VHost")] = na->GetVhostIdent() + "@" + na->GetVhostHost(); else info[_("VHost")] = na->GetVhostHost(); diff --git a/modules/commands/os_defcon.cpp b/modules/commands/os_defcon.cpp index 741eb9d43..1d684bc27 100644 --- a/modules/commands/os_defcon.cpp +++ b/modules/commands/os_defcon.cpp @@ -323,14 +323,6 @@ class OSDefcon : public Module Log() << "DefConChanModes must lock mode +l as well to lock mode +L"; } - - /* Some ircd we can't set NOKNOCK without INVITE */ - /* So check if we need there is a NOKNOCK MODE and that we need INVITEONLY */ - if (ircd->knock_needs_i && (cm = ModeManager::FindChannelModeByName(CMODE_NOKNOCK)) && DConfig.DefConModesOn.HasFlag(cm->Name) && !DConfig.DefConModesOn.HasFlag(CMODE_INVITE)) - { - DConfig.DefConModesOn.UnsetFlag(CMODE_NOKNOCK); - Log() << "DefConChanModes must lock mode +i as well to lock mode +K"; - } } public: @@ -437,7 +429,7 @@ class OSDefcon : public Module return EVENT_CONTINUE; } - EventReturn OnChannelModeSet(Channel *c, User *setter, ChannelModeName Name, const Anope::string ¶m) anope_override + EventReturn OnChannelModeSet(Channel *c, MessageSource &, ChannelModeName Name, const Anope::string ¶m) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(Name); @@ -451,7 +443,7 @@ class OSDefcon : public Module return EVENT_CONTINUE; } - EventReturn OnChannelModeUnset(Channel *c, User *setter, ChannelModeName Name, const Anope::string &) anope_override + EventReturn OnChannelModeUnset(Channel *c, MessageSource &, ChannelModeName Name, const Anope::string &) anope_override { ChannelMode *cm = ModeManager::FindChannelModeByName(Name); diff --git a/modules/commands/os_forbid.cpp b/modules/commands/os_forbid.cpp index 4862d5ea9..5f1d1d0ed 100644 --- a/modules/commands/os_forbid.cpp +++ b/modules/commands/os_forbid.cpp @@ -278,7 +278,7 @@ class OSForbid : public Module ForbidData *d = this->forbidService.FindForbid(c->name, FT_CHAN); if (bi != NULL && d != NULL) { - if (ircd->chansqline) + if (ircdproto->CanSQLineChannel) { XLine x(c->name, bi->nick, Anope::CurTime + Config->CSInhabit, d->reason); ircdproto->SendSQLine(NULL, &x); diff --git a/modules/commands/os_jupe.cpp b/modules/commands/os_jupe.cpp index 34c28a864..cfe917c13 100644 --- a/modules/commands/os_jupe.cpp +++ b/modules/commands/os_jupe.cpp @@ -37,7 +37,7 @@ class CommandOSJupe : public Command Anope::string rbuf = "Juped by " + source.GetNick() + (!reason.empty() ? ": " + reason : ""); if (server) ircdproto->SendSquit(server, rbuf); - Server *juped_server = new Server(Me, jserver, 1, rbuf, ircd->ts6 ? ts6_sid_retrieve() : "", SERVER_JUPED); + Server *juped_server = new Server(Me, jserver, 1, rbuf, ts6_sid_retrieve(), SERVER_JUPED); ircdproto->SendServer(juped_server); Log(LOG_ADMIN, source, this) << "on " << jserver << " (" << rbuf << ")"; diff --git a/modules/commands/os_oline.cpp b/modules/commands/os_oline.cpp index a468281e0..ccf053f7e 100644 --- a/modules/commands/os_oline.cpp +++ b/modules/commands/os_oline.cpp @@ -72,7 +72,7 @@ class OSOLine : public Module { this->SetAuthor("Anope"); - if (!ircd || !ircd->omode) + if (!ircdproto || !ircdproto->CanSVSO) throw ModuleException("Your IRCd does not support OMODE."); } diff --git a/modules/commands/os_stats.cpp b/modules/commands/os_stats.cpp index 7b593e421..dd5bf9ee0 100644 --- a/modules/commands/os_stats.cpp +++ b/modules/commands/os_stats.cpp @@ -84,7 +84,7 @@ class CommandOSStats : public Command else source.Reply(_("Default AKILL expiry time: \002No expiration\002")); } - if (ircd->snline && snlines) + if (ircdproto->CanSNLine && snlines) { /* SNLINEs */ source.Reply(_("Current number of SNLINEs: \002%d\002"), snlines->GetCount()); @@ -104,7 +104,7 @@ class CommandOSStats : public Command else source.Reply(_("Default SNLINE expiry time: \002No expiration\002")); } - if (ircd->sqline && sqlines) + if (ircdproto->CanSQLine && sqlines) { /* SQLINEs */ source.Reply(_("Current number of SQLINEs: \002%d\002"), sqlines->GetCount()); diff --git a/modules/commands/os_svsnick.cpp b/modules/commands/os_svsnick.cpp index aeaa38a59..4c6329acb 100644 --- a/modules/commands/os_svsnick.cpp +++ b/modules/commands/os_svsnick.cpp @@ -81,7 +81,7 @@ class OSSVSNick : public Module { this->SetAuthor("Anope"); - if (!ircd || !ircd->svsnick) + if (!ircdproto || !ircdproto->CanSVSNick) throw ModuleException("Your IRCd does not support SVSNICK"); } diff --git a/modules/commands/os_sxline.cpp b/modules/commands/os_sxline.cpp index 20e76a94d..8cd3d9f7a 100644 --- a/modules/commands/os_sxline.cpp +++ b/modules/commands/os_sxline.cpp @@ -250,7 +250,7 @@ class CommandOSSNLine : public CommandOSSXLineBase void OnAdd(CommandSource &source, const std::vector ¶ms) anope_override { - if (!this->xlm() ||! ircd->snline) + if (!this->xlm() || !ircdproto->CanSNLine) { source.Reply(_("Your IRCd does not support SNLINE")); return; @@ -384,18 +384,15 @@ class CommandOSSNLine : public CommandOSSXLineBase { this->xlm()->Send(source.GetUser(), x); - if (!ircd->sglineenforce) - { - Anope::string rreason = "G-Lined: " + reason; + Anope::string rreason = "G-Lined: " + reason; - for (Anope::insensitive_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) - { - User *user = it->second; - ++it; + for (Anope::insensitive_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end();) + { + User *user = it->second; + ++it; - if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->Mask, false, true)) - user->Kill(Config->ServerName, rreason); - } + if (!user->HasMode(UMODE_OPER) && user->server != Me && Anope::Match(user->realname, x->Mask, false, true)) + user->Kill(Config->ServerName, rreason); } } @@ -474,7 +471,7 @@ class CommandOSSQLine : public CommandOSSXLineBase void OnAdd(CommandSource &source, const std::vector ¶ms) anope_override { - if (!this->xlm() || !ircd->sqline) + if (!this->xlm() || !ircdproto->CanSQLine) { source.Reply(_("Your IRCd does not support SQLINE")); return; diff --git a/modules/extra/m_chanstats.cpp b/modules/extra/m_chanstats.cpp index ed9a5f444..9d9e9dbd8 100644 --- a/modules/extra/m_chanstats.cpp +++ b/modules/extra/m_chanstats.cpp @@ -365,8 +365,9 @@ class MChanstats : public Module else Log() << "Chanstats: no database connection to " << engine; } - void OnTopicUpdated(Channel *c, User *u, const Anope::string &topic) anope_override + void OnTopicUpdated(Channel *c, const Anope::string &user, const Anope::string &topic) anope_override { + User *u = finduser(user); if (!u || !u->Account() || !c->ci || !c->ci->HasFlag(CI_STATS)) return; query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1);"; @@ -374,16 +375,17 @@ class MChanstats : public Module query.setValue("nick", GetDisplay(u)); this->RunQuery(query); } - EventReturn OnChannelModeSet(Channel *c, User *setter, ChannelModeName Name, const Anope::string ¶m) anope_override + EventReturn OnChannelModeSet(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) anope_override { - this->OnModeChange(c, setter); + this->OnModeChange(c, setter.GetUser()); return EVENT_CONTINUE; } - EventReturn OnChannelModeUnset(Channel *c, User *setter, ChannelModeName Name, const Anope::string ¶m) anope_override + EventReturn OnChannelModeUnset(Channel *c, MessageSource &setter, ChannelModeName Name, const Anope::string ¶m) anope_override { - this->OnModeChange(c, setter); + this->OnModeChange(c, setter.GetUser()); return EVENT_CONTINUE; } + private: void OnModeChange(Channel *c, User *u) { if (!u || !u->Account() || !c->ci || !c->ci->HasFlag(CI_STATS)) @@ -394,7 +396,8 @@ class MChanstats : public Module query.setValue("nick", GetDisplay(u)); this->RunQuery(query); } - void OnUserKicked(Channel *c, User *target, const Anope::string &source, const Anope::string &kickmsg) anope_override + public: + void OnUserKicked(Channel *c, User *target, MessageSource &source, const Anope::string &kickmsg) anope_override { if (!c->ci || !c->ci->HasFlag(CI_STATS)) return; @@ -406,7 +409,7 @@ class MChanstats : public Module query = "CALL " + prefix + "chanstats_proc_update(@channel@, @nick@, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0);"; query.setValue("channel", c->name); - query.setValue("nick", GetDisplay(finduser(source))); + query.setValue("nick", GetDisplay(source.GetUser())); this->RunQuery(query); } void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override diff --git a/modules/extra/m_proxyscan.cpp b/modules/extra/m_proxyscan.cpp index f7fa3fdad..e6ee4008a 100644 --- a/modules/extra/m_proxyscan.cpp +++ b/modules/extra/m_proxyscan.cpp @@ -94,7 +94,7 @@ class ProxyConnect : public ConnectionSocket } else { - if (ircd->szline) + if (ircdproto->CanSZLine) ircdproto->SendSZLine(NULL, x); else ircdproto->SendAkill(NULL, x); diff --git a/modules/extra/webcpanel/webcpanel.cpp b/modules/extra/webcpanel/webcpanel.cpp index 4970845cd..bb65387f2 100644 --- a/modules/extra/webcpanel/webcpanel.cpp +++ b/modules/extra/webcpanel/webcpanel.cpp @@ -73,7 +73,7 @@ class ModuleWebCPanel : public Module s.subsections.push_back(ss); provider->RegisterPage(&this->nickserv_info); - if (ircd && ircd->certfp) + if (ircdproto && ircdproto->CanCertFP) { ss.name = "SSL Certificates"; ss.url = "/nickserv/cert"; diff --git a/modules/protocol/bahamut.cpp b/modules/protocol/bahamut.cpp index 73955149d..8aeee39c8 100644 --- a/modules/protocol/bahamut.cpp +++ b/modules/protocol/bahamut.cpp @@ -13,34 +13,40 @@ #include "module.h" -IRCDVar myIrcd = { - "Bahamut 1.8.x", /* ircd name */ - "+", /* Modes used by pseudoclients */ - 1, /* SVSNICK */ - 0, /* Vhost */ - 1, /* Supports SNlines */ - 1, /* Supports SQlines */ - 1, /* Supports SZlines */ - 0, /* Join 2 Message */ - 1, /* Chan SQlines */ - 1, /* Quit on Kill */ - 0, /* vidents */ - 1, /* svshold */ - 1, /* time stamp on mode */ - 0, /* O:LINE */ - 1, /* UMODE */ - 1, /* No Knock requires +i */ - 0, /* Can remove User Channel Modes with SVSMODE */ - 0, /* Sglines are not enforced until user reconnects */ - 0, /* ts6 */ - "$", /* TLD Prefix for Global */ - 6, /* Max number of modes we can send per line */ - 0 /* IRCd sends a SSL users certificate fingerprint */ -}; +class ChannelModeFlood : public ChannelModeParam +{ + public: + ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + bool IsValid(const Anope::string &value) const anope_override + { + try + { + Anope::string rest; + if (!value.empty() && value[0] != ':' && convertTo(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo(rest.substr(1), rest, false) > 0 && rest.empty()) + return true; + } + catch (const ConvertException &) { } + + return false; + } +}; class BahamutIRCdProto : public IRCDProto { + public: + BahamutIRCdProto() : IRCDProto("Bahamut 1.8.x") + { + DefaultPseudoclientModes = "+"; + CanSVSNick = true; + CanSNLine = true; + CanSQLine = true; + CanSQLineChannel = true; + CanSZLine = true; + CanSVSHold = true; + MaxModes = 60; + } + void SendModeInternal(const BotInfo *source, const Channel *dest, const Anope::string &buf) anope_override { if (Capab.count("TSMODE") > 0) @@ -62,6 +68,16 @@ class BahamutIRCdProto : public IRCDProto UplinkSocket::Message(Me) << "SVSMODE " << u->nick << " " << u->timestamp << " " << buf; } + void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg; + } + + void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg; + } + /* SVSHOLD - set */ void SendSVSHold(const Anope::string &nick) anope_override { @@ -290,46 +306,82 @@ class BahamutIRCdProto : public IRCDProto } }; -class BahamutIRCdMessage : public IRCdMessage +struct IRCDMessageBurst : IRCDMessage { - public: - bool OnMode(const Anope::string &source, const std::vector ¶ms) anope_override - { - if (params.size() > 2 && (params[0][0] == '#' || params[0][0] == '&')) - do_cmode(source, params[0], params[2], params[1]); - else if (params.size() > 1) - do_umode(params[0], params[1]); + IRCDMessageBurst() : IRCDMessage("BURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + bool Run(MessageSource &source, const std::vector ¶ms) anope_override + { + /* If we found a server with the given source, that one just + * finished bursting. If there was no source, then our uplink + * server finished bursting. -GD + */ + Server *s = source.GetServer(); + if (!s) + s = Me->GetLinks().front(); + if (s) + s->Sync(true); return true; } +}; - /* - ** NICK - new - ** source = NULL - ** parv[0] = nickname - ** parv[1] = hopcount - ** parv[2] = timestamp - ** parv[3] = modes - ** parv[4] = username - ** parv[5] = hostname - ** parv[6] = server - ** parv[7] = servicestamp - ** parv[8] = IP - ** parv[9] = info - ** NICK - change - ** source = oldnick - ** parv[0] = new nickname - ** parv[1] = hopcount - */ - bool OnNick(const Anope::string &source, const std::vector ¶ms) anope_override - { - if (params.size() != 2) +struct IRCDMessageMode : IRCDMessage +{ + IRCDMessageMode(const Anope::string &n) : IRCDMessage(n, 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override + { + if (params.size() > 2 && ircdproto->IsChannelValid(params[0])) + { + Channel *c = findchan(params[0]); + time_t ts = Anope::CurTime; + try + { + ts = convertTo(params[1]); + } + catch (const ConvertException &) { } + + if (c) + c->SetModesInternal(source, params[2], ts); + } + else { - /* Currently bahamut has no ipv6 support */ - sockaddrs ip; - ip.ntop(AF_INET, params[8].c_str()); + User *u = finduser(params[0]); + if (u) + u->SetModesInternal("%s", params[1].c_str()); + } + + return true; + } +}; + +/* + ** NICK - new + ** source = NULL + ** parv[0] = nickname + ** parv[1] = hopcount + ** parv[2] = timestamp + ** parv[3] = modes + ** parv[4] = username + ** parv[5] = hostname + ** parv[6] = server + ** parv[7] = servicestamp + ** parv[8] = IP + ** parv[9] = info + ** NICK - change + ** source = oldnick + ** parv[0] = new nickname + ** parv[1] = hopcount + */ +struct IRCDMessageNick : IRCDMessage +{ + IRCDMessageNick() : IRCDMessage("NICK", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } - User *user = do_nick(source, params[0], params[4], params[5], params[6], params[9], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : 0, ip.addr(), "", "", params[3]); + bool Run(MessageSource &source, const std::vector ¶ms) anope_override + { + if (params.size() == 10) + { + User *user = new User(params[0], params[4], params[5], "", params[8], source.GetServer(), params[9], params[2].is_pos_number_only() ? convertTo(params[2]) : 0, params[3]); if (user && nickserv) { const NickAlias *na; @@ -345,35 +397,29 @@ class BahamutIRCdMessage : public IRCdMessage } } else - do_nick(source, params[0], "", "", "", "", Anope::string(params[1]).is_pos_number_only() ? convertTo(params[1]) : 0, "", "", "", ""); + source.GetUser()->ChangeNick(params[0]); return true; } +}; - bool OnServer(const Anope::string &source, const std::vector ¶ms) anope_override - { - do_server(source, params[0], Anope::string(params[1]).is_pos_number_only() ? convertTo(params[1]) : 0, params[2], ""); - return true; - } +struct IRCDMessageServer : IRCDMessage +{ + IRCDMessageServer() : IRCDMessage("SERVER", 3) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } - bool OnTopic(const Anope::string &, const std::vector ¶ms) anope_override + bool Run(MessageSource &source, const std::vector ¶ms) anope_override { - if (params.size() < 4) - return true; - - Channel *c = findchan(params[0]); - if (!c) - { - Log() << "TOPIC for nonexistant channel " << params[0]; - return true; - } - - c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : Anope::CurTime); - + unsigned int hops = Anope::string(params[1]).is_pos_number_only() ? convertTo(params[1]) : 0; + new Server(source.GetServer() == NULL ? Me : source.GetServer(), params[0], hops, params[2]); return true; } +}; - bool OnSJoin(const Anope::string &source, const std::vector ¶ms) anope_override +struct IRCDMessageSJoin : IRCDMessage +{ + IRCDMessageSJoin() : IRCDMessage("SJOIN", 2) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override { Channel *c = findchan(params[1]); time_t ts = Anope::string(params[0]).is_pos_number_only() ? convertTo(params[0]) : 0; @@ -403,7 +449,7 @@ class BahamutIRCdMessage : public IRCdMessage modes += " " + params[i]; if (!modes.empty()) modes.erase(modes.begin()); - c->SetModesInternal(NULL, modes); + c->SetModesInternal(source, modes); } /* For some reason, bahamut will send a SJOIN from the user joining a channel @@ -411,28 +457,24 @@ class BahamutIRCdMessage : public IRCdMessage */ if (!c->HasFlag(CH_SYNCING) && params.size() == 2) { - User *u = finduser(source); - if (!u) - Log(LOG_DEBUG) << "SJOIN for nonexistant user " << source << " on " << c->name; - else - { - EventReturn MOD_RESULT; - FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); + User *u = source.GetUser(); - /* Add the user to the channel */ - c->JoinUser(u); + EventReturn MOD_RESULT; + FOREACH_RESULT(I_OnPreJoinChannel, OnPreJoinChannel(u, c)); - /* Now set whatever modes this user is allowed to have on the channel */ - chan_set_correct_modes(u, c, 1, true); + /* Add the user to the channel */ + c->JoinUser(u); - /* Check to see if modules want the user to join, if they do - * check to see if they are allowed to join (CheckKick will kick/ban them) - * Don't trigger OnJoinChannel event then as the user will be destroyed - */ - if (MOD_RESULT == EVENT_STOP && (!c->ci || !c->ci->CheckKick(u))) - { - FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); - } + /* Now set whatever modes this user is allowed to have on the channel */ + chan_set_correct_modes(u, c, 1, true); + + /* Check to see if modules want the user to join, if they do + * check to see if they are allowed to join (CheckKick will kick/ban them) + * Don't trigger OnJoinChannel event then as the user will be destroyed + */ + if (MOD_RESULT == EVENT_STOP && (!c->ci || !c->ci->CheckKick(u))) + { + FOREACH_MOD(I_OnJoinChannel, OnJoinChannel(u, c)); } } else @@ -476,7 +518,7 @@ class BahamutIRCdMessage : public IRCdMessage * This will enforce secureops etc on the user */ for (std::list::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it) - c->SetModeInternal(NULL, *it, buf); + c->SetModeInternal(source, *it, buf); /* Now set whatever modes this user is allowed to have on the channel */ chan_set_correct_modes(u, c, 1, true); @@ -504,53 +546,48 @@ class BahamutIRCdMessage : public IRCdMessage } }; -bool event_burst(const Anope::string &source, const std::vector ¶ms) -{ - Server *s = Server::Find(source); - - if (params.empty()) - { - /* for future use - start burst */ - } - else - { - /* If we found a server with the given source, that one just - * finished bursting. If there was no source, then our uplink - * server finished bursting. -GD - */ - if (!s) - s = Me->GetLinks().front(); - if (s) - s->Sync(true); - } - return true; -} - -class ChannelModeFlood : public ChannelModeParam +struct IRCDMessageTopic : IRCDMessage { - public: - ChannelModeFlood(char modeChar, bool minusNoArg) : ChannelModeParam(CMODE_FLOOD, modeChar, minusNoArg) { } + IRCDMessageTopic() : IRCDMessage("TOPIC", 4) { } - bool IsValid(const Anope::string &value) const anope_override + bool Run(MessageSource &, const std::vector ¶ms) anope_override { - try - { - Anope::string rest; - if (!value.empty() && value[0] != ':' && convertTo(value[0] == '*' ? value.substr(1) : value, rest, false) > 0 && rest[0] == ':' && rest.length() > 1 && convertTo(rest.substr(1), rest, false) > 0 && rest.empty()) - return true; - } - catch (const ConvertException &) { } - - return false; + Channel *c = findchan(params[0]); + if (c) + c->ChangeTopicInternal(params[1], params[3], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : Anope::CurTime); + return true; } }; class ProtoBahamut : public Module { - Message message_svsmode, message_burst; - BahamutIRCdProto ircd_proto; - BahamutIRCdMessage ircd_message; + + /* Core message handlers */ + CoreIRCDMessageAway core_message_away; + CoreIRCDMessageCapab core_message_capab; + CoreIRCDMessageError core_message_error; + CoreIRCDMessageJoin core_message_join; + CoreIRCDMessageKill core_message_kill; + CoreIRCDMessageMOTD core_message_motd; + CoreIRCDMessagePart core_message_part; + CoreIRCDMessagePing core_message_ping; + CoreIRCDMessagePrivmsg core_message_privmsg; + CoreIRCDMessageQuit core_message_quit; + CoreIRCDMessageSQuit core_message_squit; + CoreIRCDMessageStats core_message_stats; + CoreIRCDMessageTime core_message_time; + CoreIRCDMessageTopic core_message_topic; + CoreIRCDMessageVersion core_message_version; + CoreIRCDMessageWhois core_message_whois; + + /* Our message handlers */ + IRCDMessageBurst message_burst; + IRCDMessageMode message_mode, message_svsmode; + IRCDMessageNick message_nick; + IRCDMessageServer message_server; + IRCDMessageSJoin message_sjoin; + IRCDMessageTopic message_topic; void AddModes() { @@ -591,26 +628,15 @@ class ProtoBahamut : public Module public: ProtoBahamut(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, PROTOCOL), - message_svsmode("SVSMODE", OnMode), message_burst("BURST", event_burst) + message_mode("MODE"), message_svsmode("SVSMODE") { this->SetAuthor("Anope"); - pmodule_ircd_var(&myIrcd); - pmodule_ircd_proto(&this->ircd_proto); - pmodule_ircd_message(&this->ircd_message); - this->AddModes(); ModuleManager::Attach(I_OnUserNickChange, this); } - ~ProtoBahamut() - { - pmodule_ircd_var(NULL); - pmodule_ircd_proto(NULL); - pmodule_ircd_message(NULL); - } - void OnUserNickChange(User *u, const Anope::string &) anope_override { u->RemoveModeInternal(ModeManager::FindUserModeByName(UMODE_REGISTERED)); diff --git a/modules/protocol/inspircd-ts6.h b/modules/protocol/inspircd-ts6.h index 0ce5be921..f0af01cc9 100644 --- a/modules/protocol/inspircd-ts6.h +++ b/modules/protocol/inspircd-ts6.h @@ -47,7 +47,30 @@ class InspIRCdTS6Proto : public IRCDProto UplinkSocket::Message(Me) << "CHGHOST " << nick << " " << vhost; } - public: + protected: + InspIRCdTS6Proto(const Anope::string &name) : IRCDProto(name) + { + DefaultPseudoclientModes = "+I"; + CanSVSNick = true; + CanSetVHost = true; + CanSetVIdent = true; + CanSQLine = true; + CanSZLine = true; + CanSVSHold = true; + CanCertFP = true; + RequiresID = true; + MaxModes = 20; + } + + void SendGlobalNotice(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "NOTICE $" << dest->GetName() << " :" << msg; + } + + void SendGlobalPrivmsg(const BotInfo *bi, const Server *dest, const Anope::string &msg) anope_override + { + UplinkSocket::Message(bi) << "PRIVMSG $" << dest->GetName() << " :" << msg; + } void SendAkillDel(const XLine *x) anope_override { @@ -225,7 +248,7 @@ class InspIRCdTS6Proto : public IRCDProto SendServer(Me); UplinkSocket::Message(Me) << "BURST"; Module *enc = ModuleManager::FindFirstOf(ENCRYPTION); - UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << ircd->name << " - (" << (enc ? enc->name : "unknown") << ") -- " << Anope::VersionBuildString(); + UplinkSocket::Message(Me) << "VERSION :Anope-" << Anope::Version() << " " << Config->ServerName << " :" << ircdproto->GetProtocolName() << " - (" << (enc ? enc->name : "unknown") << ") -- " << Anope::VersionBuildString(); } /* SVSHOLD - set */ @@ -319,83 +342,37 @@ class InspIRCdTS6Proto : public IRCDProto } }; -class InspircdIRCdMessage : public IRCdMessage +struct IRCDMessageEndburst : IRCDMessage { - public: - bool OnMode(const Anope::string &source, const std::vector ¶ms) anope_override - { - if (params[0][0] == '#' || params[0][0] == '&') - do_cmode(source, params[0], params[2], params[1]); - else - { - /* InspIRCd lets opers change another - users modes, we have to kludge this - as it slightly breaks RFC1459 - */ - User *u = finduser(source); - // This can happen with server-origin modes. - if (!u) - u = finduser(params[0]); - // if it's still null, drop it like fire. - // most likely situation was that server introduced a nick which we subsequently akilled - if (!u) - return true; + IRCDMessageEndburst() : IRCDMessage("ENDBURST", 0) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); } - do_umode(u->nick, params[1]); - } - - return true; - } - - virtual bool OnUID(const Anope::string &source, const std::vector ¶ms) anope_override = 0; - - bool OnNick(const Anope::string &source, const std::vector ¶ms) anope_override + bool Run(MessageSource &source, const std::vector ¶ms) anope_override { - do_nick(source, params[0], "", "", "", "", 0, "", "", "", ""); - return true; - } - - bool OnPrivmsg(const Anope::string &source, const std::vector ¶ms) anope_override - { - /* Ignore privmsgs from the server, which can happen. */ - if (Server::Find(source) != NULL) - return true; + Server *s = source.GetServer(); - return IRCdMessage::OnPrivmsg(source, params); - } + Log(LOG_DEBUG) << "Processed ENDBURST for " << s->GetName(); - /* - * [Nov 04 00:08:46.308435 2009] debug: Received: SERVER irc.inspircd.com pass 0 964 :Testnet Central! - * 0: name - * 1: pass - * 2: hops - * 3: numeric - * 4: desc - */ - bool OnServer(const Anope::string &source, const std::vector ¶ms) anope_override - { - do_server(source, params[0], Anope::string(params[2]).is_pos_number_only() ? convertTo(params[2]) : 0, params[4], params[3]); + s->Sync(true); return true; } +}; - bool OnTopic(const Anope::string &source, const std::vector ¶ms) anope_override - { - Channel *c = findchan(params[0]); - - if (!c) - { - Log() << "TOPIC " << params[1] << " for nonexistent channel " << params[0]; - return true; - } - - c->ChangeTopicInternal(source, (params.size() > 1 ? params[1] : ""), Anope::CurTime); +struct IRCDMessageFHost : IRCDMessage +{ + IRCDMessageFHost(const Anope::string &n) : IRCDMessage(n, 1) { SetFlag(IRCDMESSAGE_REQUIRE_USER); } + bool Run(MessageSource &source, const std::vector ¶ms) anope_override + { + source.GetUser()->SetDisplayedHost(params[0]); return true; } +}; - virtual bool OnCapab(const Anope::string &, const std::vector &) anope_override = 0; +struct IRCDMessageFJoin : IRCDMessage +{ + IRCDMessageFJoin() : IRCDMessage("FJOIN", 2) { SetFlag(IRCDMESSAGE_REQUIRE_SERVER); SetFlag(IRCDMESSAGE_SOFT_LIMIT); } - bool OnSJoin(const Anope::string &source, const std::vector ¶ms) anope_override + bool Run(MessageSource &source, const std::vector ¶ms) anope_override { Channel *c = findchan(params[0]); time_t ts = Anope::string(params[1]).is_pos_number_only() ? convertTo(params[1]) : 0; @@ -425,7 +402,7 @@ class InspircdIRCdMessage : public IRCdMessage if (!modes.empty()) modes.erase(modes.begin()); /* Set the modes internally */ - c->SetModesInternal(NULL, modes); + c->SetModesInternal(source, modes); } spacesepstream sep(params[params.size() - 1]); @@ -468,7 +445,7 @@ class InspircdIRCdMessage : public IRCdMessage * This will enforce secureops etc on the user */ for (std::list::iterator it = Status.begin(), it_end = Status.end(); it != it_end; ++it) - c->SetModeInternal(NULL, *it, buf); + c->SetModeInternal(source, *it, buf); /* Now set whatever modes this user is allowed to have on the channel */ chan_set_correct_modes(u, c, 1, true); @@ -495,33 +472,268 @@ class InspircdIRCdMessage : public IRCdMessage } }; -bool event_idle(const Anope::string &source, const std::vector ¶ms) +struct IRCDMessageFMode : IRCDMessage +{ + IRCDMessageFMode() : IRCDMessage("FMODE", 3) { SetFlag(IRCDMESSAGE_SOFT_LIMIT); } + + bool Run(MessageSource &source, const std::vector ¶ms) anope_override + { + /* :source FMODE #test 12345678 +nto foo */ + + Anope::string modes = params[2]; + for (unsigned n = 3; n < params.size(); ++n) + modes += " " + params[n]; + + Channel *c = findchan(params[0]); + time_t ts; + + try + { + ts = convertTo(params[1]); + } + catch (const ConvertException &) + { + ts = Anope::CurTime; + } + + if (c) + c->SetModesInternal(source, modes, ts); + + return true; + } +}; + +st