summaryrefslogtreecommitdiff
path: root/src/modules/m_nickflood.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules/m_nickflood.cpp')
-rw-r--r--src/modules/m_nickflood.cpp114
1 files changed, 48 insertions, 66 deletions
diff --git a/src/modules/m_nickflood.cpp b/src/modules/m_nickflood.cpp
index 04d7c8b5e..17d6db956 100644
--- a/src/modules/m_nickflood.cpp
+++ b/src/modules/m_nickflood.cpp
@@ -19,8 +19,10 @@
#include "inspircd.h"
+#include "modules/exemption.h"
-/* $ModDesc: Provides channel mode +F (nick flood protection) */
+// The number of seconds nickname changing will be blocked for.
+static unsigned int duration;
/** Holds settings and state associated with channel mode +F
*/
@@ -74,101 +76,85 @@ class nickfloodsettings
void lock()
{
- unlocktime = ServerInstance->Time() + 60;
+ unlocktime = ServerInstance->Time() + duration;
}
};
/** Handles channel mode +F
*/
-class NickFlood : public ModeHandler
+class NickFlood : public ParamMode<NickFlood, SimpleExtItem<nickfloodsettings> >
{
public:
- SimpleExtItem<nickfloodsettings> ext;
- NickFlood(Module* Creator) : ModeHandler(Creator, "nickflood", 'F', PARAM_SETONLY, MODETYPE_CHANNEL),
- ext("nickflood", Creator) { }
+ NickFlood(Module* Creator)
+ : ParamMode<NickFlood, SimpleExtItem<nickfloodsettings> >(Creator, "nickflood", 'F')
+ {
+ }
- ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
+ ModeAction OnSet(User* source, Channel* channel, std::string& parameter) CXX11_OVERRIDE
{
- if (adding)
+ std::string::size_type colon = parameter.find(':');
+ if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
{
- std::string::size_type colon = parameter.find(':');
- if ((colon == std::string::npos) || (parameter.find('-') != std::string::npos))
- {
- source->WriteNumeric(608, "%s %s :Invalid flood parameter",source->nick.c_str(),channel->name.c_str());
- return MODEACTION_DENY;
- }
-
- /* Set up the flood parameters for this channel */
- unsigned int nnicks = ConvToInt(parameter.substr(0, colon));
- unsigned int nsecs = ConvToInt(parameter.substr(colon+1));
-
- if ((nnicks<1) || (nsecs<1))
- {
- source->WriteNumeric(608, "%s %s :Invalid flood parameter",source->nick.c_str(),channel->name.c_str());
- return MODEACTION_DENY;
- }
+ source->WriteNumeric(Numerics::InvalidModeParameter(channel, this, parameter));
+ return MODEACTION_DENY;
+ }
- nickfloodsettings* f = ext.get(channel);
- if ((f) && (nnicks == f->nicks) && (nsecs == f->secs))
- // mode params match
- return MODEACTION_DENY;
+ /* Set up the flood parameters for this channel */
+ unsigned int nnicks = ConvToNum<unsigned int>(parameter.substr(0, colon));
+ unsigned int nsecs = ConvToNum<unsigned int>(parameter.substr(colon+1));
- ext.set(channel, new nickfloodsettings(nsecs, nnicks));
- parameter = ConvToStr(nnicks) + ":" + ConvToStr(nsecs);
- channel->SetModeParam('F', parameter);
- return MODEACTION_ALLOW;
- }
- else
+ if ((nnicks<1) || (nsecs<1))
{
- if (!channel->IsModeSet('F'))
- return MODEACTION_DENY;
-
- ext.unset(channel);
- channel->SetModeParam('F', "");
- return MODEACTION_ALLOW;
+ source->WriteNumeric(Numerics::InvalidModeParameter(channel, this, parameter));
+ return MODEACTION_DENY;
}
+
+ ext.set(channel, new nickfloodsettings(nsecs, nnicks));
+ return MODEACTION_ALLOW;
+ }
+
+ void SerializeParam(Channel* chan, const nickfloodsettings* nfs, std::string& out)
+ {
+ out.append(ConvToStr(nfs->nicks)).push_back(':');
+ out.append(ConvToStr(nfs->secs));
}
};
class ModuleNickFlood : public Module
{
+ CheckExemption::EventProvider exemptionprov;
NickFlood nf;
public:
-
ModuleNickFlood()
- : nf(this)
+ : exemptionprov(this)
+ , nf(this)
{
}
- void init()
+ void ReadConfig(ConfigStatus&) CXX11_OVERRIDE
{
- ServerInstance->Modules->AddService(nf);
- ServerInstance->Modules->AddService(nf.ext);
- Implementation eventlist[] = { I_OnUserPreNick, I_OnUserPostNick };
- ServerInstance->Modules->Attach(eventlist, this, sizeof(eventlist)/sizeof(Implementation));
+ ConfigTag* tag = ServerInstance->Config->ConfValue("nickflood");
+ duration = tag->getDuration("duration", 60, 10, 600);
}
- ModResult OnUserPreNick(User* user, const std::string &newnick)
+ ModResult OnUserPreNick(LocalUser* user, const std::string& newnick) CXX11_OVERRIDE
{
- if (ServerInstance->NICKForced.get(user)) /* Allow forced nick changes */
- return MOD_RES_PASSTHRU;
-
- for (UCListIter i = user->chans.begin(); i != user->chans.end(); i++)
+ for (User::ChanList::iterator i = user->chans.begin(); i != user->chans.end(); i++)
{
- Channel *channel = *i;
+ Channel* channel = (*i)->chan;
ModResult res;
nickfloodsettings *f = nf.ext.get(channel);
if (f)
{
- res = ServerInstance->OnCheckExemption(user,channel,"nickflood");
+ res = CheckExemption::Call(exemptionprov, user, channel, "nickflood");
if (res == MOD_RES_ALLOW)
continue;
if (f->islocked())
{
- user->WriteNumeric(447, "%s :%s has been locked for nickchanges for 60 seconds because there have been more than %u nick changes in %u seconds", user->nick.c_str(), channel->name.c_str(), f->nicks, f->secs);
+ user->WriteNumeric(ERR_CANTCHANGENICK, InspIRCd::Format("%s has been locked for nickchanges for %u seconds because there have been more than %u nick changes in %u seconds", channel->name.c_str(), duration, f->nicks, f->secs));
return MOD_RES_DENY;
}
@@ -176,7 +162,7 @@ class ModuleNickFlood : public Module
{
f->clear();
f->lock();
- channel->WriteChannelWithServ((char*)ServerInstance->Config->ServerName.c_str(), "NOTICE %s :No nick changes are allowed for 60 seconds because there have been more than %u nick changes in %u seconds.", channel->name.c_str(), f->nicks, f->secs);
+ channel->WriteNotice(InspIRCd::Format("No nick changes are allowed for %u seconds because there have been more than %u nick changes in %u seconds.", duration, f->nicks, f->secs));
return MOD_RES_DENY;
}
}
@@ -188,20 +174,20 @@ class ModuleNickFlood : public Module
/*
* XXX: HACK: We do the increment on the *POST* event here (instead of all together) because we have no way of knowing whether other modules would block a nickchange.
*/
- void OnUserPostNick(User* user, const std::string &oldnick)
+ void OnUserPostNick(User* user, const std::string &oldnick) CXX11_OVERRIDE
{
if (isdigit(user->nick[0])) /* allow switches to UID */
return;
- for (UCListIter i = user->chans.begin(); i != user->chans.end(); ++i)
+ for (User::ChanList::iterator i = user->chans.begin(); i != user->chans.end(); ++i)
{
- Channel *channel = *i;
+ Channel* channel = (*i)->chan;
ModResult res;
nickfloodsettings *f = nf.ext.get(channel);
if (f)
{
- res = ServerInstance->OnCheckExemption(user,channel,"nickflood");
+ res = CheckExemption::Call(exemptionprov, user, channel, "nickflood");
if (res == MOD_RES_ALLOW)
return;
@@ -214,13 +200,9 @@ class ModuleNickFlood : public Module
}
}
- ~ModuleNickFlood()
- {
- }
-
- Version GetVersion()
+ Version GetVersion() CXX11_OVERRIDE
{
- return Version("Channel mode F - nick flood protection", VF_VENDOR);
+ return Version("Provides channel mode +F, nick flood protection", VF_VENDOR);
}
};