summaryrefslogtreecommitdiff
path: root/src/modules
diff options
context:
space:
mode:
Diffstat (limited to 'src/modules')
-rw-r--r--src/modules/m_messageflood.cpp73
-rw-r--r--src/modules/m_spanningtree.cpp19
2 files changed, 90 insertions, 2 deletions
diff --git a/src/modules/m_messageflood.cpp b/src/modules/m_messageflood.cpp
index 738857f29..0f0878646 100644
--- a/src/modules/m_messageflood.cpp
+++ b/src/modules/m_messageflood.cpp
@@ -17,6 +17,7 @@
using namespace std;
#include <stdio.h>
+#include <map>
#include "users.h"
#include "channels.h"
#include "modules.h"
@@ -30,9 +31,45 @@ class floodsettings
bool ban;
int secs;
int lines;
+ time_t reset;
+ std::map<userrec*,int> counters;
floodsettings() : ban(0), secs(0), lines(0) {};
- floodsettings(bool a, int b, int c) : ban(a), secs(b), lines(c) {};
+ floodsettings(bool a, int b, int c) : ban(a), secs(b), lines(c) { reset = time(NULL) + secs };
+
+ void addmessage(userrec* who)
+ {
+ std::map<userrec*,int>::iterator iter = counters.find(who);
+ if (iter != counters.end())
+ {
+ iter->second++;
+ log(DEBUG,"Count for %s is now %d",who->nick,iter->second);
+ }
+ if (reset > time(NULL))
+ {
+ counters.clear();
+ reset = time(NULL) + secs;
+ }
+ }
+
+ bool shouldkick(userrec* who)
+ {
+ std::map<userrec*,int>::iterator iter = counters.find(who);
+ if (iter != counters.end())
+ {
+ return (iter->second >= this->lines);
+ }
+ else return false;
+ }
+
+ void clear(userrec* who)
+ {
+ std::map<userrec*,int>::iterator iter = counters.find(who);
+ if (iter != counters.end())
+ {
+ counters.erase(iter);
+ }
+ }
};
class ModuleMsgFlood : public Module
@@ -124,6 +161,40 @@ class ModuleMsgFlood : public Module
return 0;
}
+ int ProcessMessages(userrec* user,chanrec* dest,std::string &text)
+ {
+ floodsettings *f = (floodsettings*)c->GetExt("flood");
+ if (f)
+ {
+ f->addmessage(user);
+ if (f->shouldkick(user))
+ {
+ /* Youre outttta here! */
+ f->clear(user);
+ Srv->KickUser(NULL, user, dest, "Channel flood triggered (mode +f)");
+ return 1;
+ }
+ }
+ }
+
+ virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text)
+ {
+ if (target_type == TYPE_CHANNEL)
+ {
+ return ProcessMessages(user,(chanrec*)dest,text);
+ }
+ else return 0;
+ }
+
+ virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text)
+ {
+ if (target_type == TYPE_CHANNEL)
+ {
+ return ProcessMessages(user,(chanrec*)dest,text);
+ }
+ else return 0;
+ }
+
void OnChannelDelete(chanrec* chan)
{
if (chan->GetExt("flood"))
diff --git a/src/modules/m_spanningtree.cpp b/src/modules/m_spanningtree.cpp
index 124583ff1..7204c2435 100644
--- a/src/modules/m_spanningtree.cpp
+++ b/src/modules/m_spanningtree.cpp
@@ -2029,6 +2029,14 @@ class TreeSocket : public InspSocket
{
return this->ForceTopic(prefix,params);
}
+ else if ((command == "KICK") && (!Srv->FindNick(prefix)))
+ {
+ /* Server kick */
+ userrec* who = Srv->FindNick(params[1]);
+ chanrec* where = Srv->FindChannel(params[0]);
+ server_kick_channel(who, where, (char*)params[2].c_str(), false);
+ return true;
+ }
else if (command == "REHASH")
{
return this->RemoteRehash(prefix,params);
@@ -3054,7 +3062,16 @@ class ModuleSpanningTree : public Module
virtual void OnUserKick(userrec* source, userrec* user, chanrec* chan, std::string reason)
{
- if (source->fd > -1)
+ if (!source)
+ {
+ /* Server kick (ugh) */
+ std::deque<std::string> params;
+ params.push_back(chan->name);
+ params.push_back(user->nick);
+ params.push_back(":"+reason);
+ DoOneToMany(Srv->GetServerName(),"KICK",params);
+ }
+ else if (source->fd > -1)
{
std::deque<std::string> params;
params.push_back(chan->name);