/* $ModDesc: Provides channel mode +f (message flood protection) */
-class floodsettings
+class floodsettings : public classbase
{
public:
bool ban;
public:
MsgFlood() : ModeHandler('f', 1, 0, false, MODETYPE_CHANNEL, false) { }
+ ModePair ModeSet(userrec* source, userrec* dest, chanrec* channel, const std::string ¶meter)
+ {
+ floodsettings* x;
+ if (channel->GetExt("flood",x))
+ return std::make_pair(true, (x->ban ? "*" : "")+ConvToStr(x->lines)+":"+ConvToStr(x->secs));
+ else
+ return std::make_pair(false, parameter);
+ }
+
+ bool CheckTimeStamp(time_t theirs, time_t ours, const std::string &their_param, const std::string &our_param, chanrec* channel)
+ {
+ /* When TS is equal, the alphabetically later one wins */
+ return (their_param < our_param);
+ }
+
ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string ¶meter, bool adding)
{
+ floodsettings *f;
+
if (adding)
{
char ndata[MAXBUF];
}
else
{
- if (!channel->GetExt("flood"))
+ if (!channel->GetExt("flood", f))
{
parameter = ConvToStr(nlines) + ":" +ConvToStr(nsecs);
floodsettings *f = new floodsettings(ban,nsecs,nlines);
- channel->Extend("flood",(char*)f);
+ channel->Extend("flood",f);
channel->SetMode('f', true);
channel->SetModeParam('f', parameter.c_str(), true);
return MODEACTION_ALLOW;
}
else
{
- if (channel->GetExt("flood"))
+ if (channel->GetExt("flood", f))
{
- floodsettings *f = (floodsettings*)channel->GetExt("flood");
DELETE(f);
channel->Shrink("flood");
channel->SetMode('f', false);
{
if (IS_LOCAL(user))
{
- floodsettings *f = (floodsettings*)dest->GetExt("flood");
- if (f)
+ floodsettings *f;
+ if (dest->GetExt("flood", f))
{
f->addmessage(user);
if (f->shouldkick(user))
f->clear(user);
if (f->ban)
{
- char* parameters[3];
+ const char* parameters[3];
parameters[0] = dest->name;
parameters[1] = "+b";
parameters[2] = user->MakeWildHost();
Srv->SendMode(parameters,3,user);
+ std::deque<std::string> n;
+ /* Propogate the ban to other servers.
+ * We dont know what protocol we may be using,
+ * so this event is picked up by our protocol
+ * module and formed into a ban command that
+ * suits the protocol in use.
+ */
+ n.push_back(dest->name);
+ n.push_back("+b");
+ n.push_back(user->MakeWildHost());
+ Event rmode((char *)&n, NULL, "send_mode");
+ rmode.Send();
}
Srv->KickUser(NULL, user, dest, "Channel flood triggered (mode +f)");
}
void OnChannelDelete(chanrec* chan)
{
- if (chan->GetExt("flood"))
+ floodsettings* f;
+ if (chan->GetExt("flood", f))
{
- floodsettings *f = (floodsettings*)chan->GetExt("flood");
DELETE(f);
chan->Shrink("flood");
}