]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_chanfilter.cpp
delete operator tracking in debug mode (using a macro -- live with it.)
[user/henk/code/inspircd.git] / src / modules / m_chanfilter.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd is copyright (C) 2002-2006 ChatSpike-Dev.
6  *                       E-mail:
7  *                <brain@chatspike.net>
8  *                <Craig@chatspike.net>
9  *     
10  * Written by Craig Edwards, Craig McLure, and others.
11  * This program is free but copyrighted software; see
12  *            the file COPYING for details.
13  *
14  * ---------------------------------------------------
15  */
16
17 using namespace std;
18
19 #include <stdio.h>
20 #include <string>
21 #include <vector>
22 #include "users.h"
23 #include "channels.h"
24 #include "modules.h"
25 #include "helperfuncs.h"
26 #include "hashcomp.h"
27
28 /* $ModDesc: Provides channel-specific censor lists (like mode +G but varies from channel to channel) */
29
30 typedef std::vector<irc::string> SpamList;
31
32 class ModuleChanFilter : public Module
33 {
34         Server *Srv;
35         ConfigReader *Conf;
36         long MaxEntries;
37         
38  public:
39  
40         ModuleChanFilter(Server* Me)
41                 : Module::Module(Me)
42         {
43                 Srv = Me;
44                 Conf = new ConfigReader;
45                 Srv->AddExtendedListMode('g');
46                 MaxEntries = Conf->ReadInteger("chanfilter","maxsize",0,true);
47                 if (MaxEntries == 0)
48                         MaxEntries = 32;
49         }
50
51         void Implements(char* List) 
52         { 
53                 List[I_On005Numeric] = List[I_OnUserPart] = List[I_OnRehash] = List[I_OnUserPreMessage] = List[I_OnUserPreNotice] = List[I_OnExtendedMode] = List[I_OnSendList] = List[I_OnSyncChannel] = 1;
54         }
55         
56         virtual void On005Numeric(std::string &output)
57         {
58                 InsertMode(output,"g",1);
59         }
60
61         virtual void OnUserPart(userrec* user, chanrec* channel, const std::string &partreason)
62         {
63                 // when the last user parts, delete the list
64                 if (Srv->CountUsers(channel) == 1)
65                 {
66                         SpamList* spamlist = (SpamList*)channel->GetExt("spam_list");
67                         if (spamlist)
68                         {
69                                 channel->Shrink("spam_list");
70                                 DELETE(spamlist);
71                         }
72                 }
73         }
74
75         virtual void OnRehash(const std::string &parameter)
76         {
77                 DELETE(Conf);
78                 Conf = new ConfigReader;
79                 // re-read our config options on a rehash
80                 MaxEntries = Conf->ReadInteger("chanfilter","maxsize",0,true);
81         }
82
83         virtual int ProcessMessages(userrec* user,chanrec* chan,std::string &text)
84         {
85
86                 // Create a copy of the string in irc::string
87                 irc::string line = text.c_str();
88
89                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
90                 if (spamlist)
91                 {
92                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
93                         {
94                                 if (line.find(*i) != std::string::npos)
95                                 {
96                                         WriteServ(user->fd,"936 %s %s %s :Your message contained a censored word, and was blocked",user->nick, chan->name, i->c_str());
97                                         return 1;
98                                 }
99                         }
100                 }
101                 return 0;
102         }
103
104         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text, char status)
105         {
106                 if (target_type == TYPE_CHANNEL)
107                 {
108                         return ProcessMessages(user,(chanrec*)dest,text);
109                 }
110                 else return 0;
111         }
112
113         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text, char status)
114         {
115                 return OnUserPreMessage(user,dest,target_type,text,status);
116         }
117         
118         virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
119         {
120                 if ((modechar == 'g') && (type == MT_CHANNEL))
121                 {
122                         chanrec* chan = (chanrec*)target;
123
124                         irc::string word = params[0].c_str();
125
126                         if (word == "")
127                                 return -1;
128
129                         if (mode_on)
130                         {
131                                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
132                                 if (!spamlist)
133                                 {
134                                         spamlist = new SpamList;
135                                         chan->Extend("spam_list",(char*)spamlist);
136                                 }
137                                 if (spamlist->size() < (unsigned)MaxEntries)
138                                 {
139                                         if (word.length() > 35)
140                                         {
141                                                 WriteServ(user->fd,"935 %s %s %s :word is too long for censor list",user->nick, chan->name,word.c_str());
142                                                 return -1;
143                                         }
144                                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
145                                         {
146                                                 if (*i == word)
147                                                 {
148                                                         WriteServ(user->fd,"937 %s %s :The word %s is already on the spamfilter list",user->nick, chan->name,word.c_str());
149                                                         return -1;
150                                                 }
151                                         }
152                                         spamlist->push_back(word);
153                                         return 1;
154                                 }
155                                 WriteServ(user->fd,"939 %s %s :Channel spamfilter list is full",user->nick, chan->name);
156                                 return -1;
157                         }
158                         else
159                         {
160                                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
161                                 if (spamlist)
162                                 {
163                                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
164                                         {
165                                                 if (*i == word)
166                                                 {
167                                                         spamlist->erase(i);
168                                                         return 1;
169                                                 }
170                                         }
171                                 }
172                                 WriteServ(user->fd,"938 %s %s :No such spamfilter word is set",user->nick, chan->name);
173                                 return -1;
174                         }
175                         return -1;
176                 }       
177                 return 0;
178         }
179
180         virtual void OnSendList(userrec* user, chanrec* channel, char mode)
181         {
182                 if (mode == 'g')
183                 {
184                         SpamList* spamlist = (SpamList*)channel->GetExt("spam_list");
185                         if (spamlist)
186                         {
187                                 for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
188                                 {
189                                         WriteServ(user->fd,"941 %s %s %s",user->nick, channel->name,i->c_str());
190                                 }
191                         }
192                         WriteServ(user->fd,"940 %s %s :End of channel spamfilter list",user->nick, channel->name);
193                 }
194         }
195         
196         virtual ~ModuleChanFilter()
197         {
198                 DELETE(Conf);
199         }
200         
201         virtual Version GetVersion()
202         {
203                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
204         }
205         
206         virtual void OnSyncChannel(chanrec* chan, Module* proto, void* opaque)
207         {
208                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
209                 string_list commands;
210                 if (spamlist)
211                 {
212                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
213                         {
214                                 proto->ProtoSendMode(opaque,TYPE_CHANNEL,chan,"+g "+std::string(i->c_str()));
215                         }
216                 }
217         }
218
219 };
220
221
222 class ModuleChanFilterFactory : public ModuleFactory
223 {
224  public:
225         ModuleChanFilterFactory()
226         {
227         }
228         
229         ~ModuleChanFilterFactory()
230         {
231         }
232         
233         virtual Module * CreateModule(Server* Me)
234         {
235                 return new ModuleChanFilter(Me);
236         }
237         
238 };
239
240
241 extern "C" void * init_module( void )
242 {
243         return new ModuleChanFilterFactory;
244 }
245