]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_chanfilter.cpp
Deny +g words >35 chars to prevent having massive words that some users can remove...
[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, 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(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 (mode_on)
127                         {
128                                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
129                                 if (!spamlist)
130                                 {
131                                         spamlist = new SpamList;
132                                         chan->Extend("spam_list",(char*)spamlist);
133                                 }
134                                 if (spamlist->size() < (unsigned)MaxEntries)
135                                 {
136                                         if (word.length() > 35)
137                                         {
138                                                 WriteServ(user->fd,"935 %s %s %s :word is too long for censor list",user->nick, chan->name,word.c_str());
139                                                 return -1;
140                                         }
141                                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
142                                         {
143                                                 if (*i == word)
144                                                 {
145                                                         WriteServ(user->fd,"937 %s %s :The word %s is already on the spamfilter list",user->nick, chan->name,word.c_str());
146                                                         return -1;
147                                                 }
148                                         }
149                                         spamlist->push_back(word);
150                                         return 1;
151                                 }
152                                 WriteServ(user->fd,"939 %s %s :Channel spamfilter list is full",user->nick, chan->name);
153                                 return -1;
154                         }
155                         else
156                         {
157                                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
158                                 if (spamlist)
159                                 {
160                                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
161                                         {
162                                                 if (*i == word)
163                                                 {
164                                                         spamlist->erase(i);
165                                                         return 1;
166                                                 }
167                                         }
168                                 }
169                                 WriteServ(user->fd,"938 %s %s :No such spamfilter word is set",user->nick, chan->name);
170                                 return -1;
171                         }
172                         return -1;
173                 }       
174                 return 0;
175         }
176
177         virtual void OnSendList(userrec* user, chanrec* channel, char mode)
178         {
179                 if (mode == 'g')
180                 {
181                         SpamList* spamlist = (SpamList*)channel->GetExt("spam_list");
182                         if (spamlist)
183                         {
184                                 for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
185                                 {
186                                         WriteServ(user->fd,"941 %s %s %s",user->nick, channel->name,i->c_str());
187                                 }
188                         }
189                         WriteServ(user->fd,"940 %s %s :End of channel spamfilter list",user->nick, channel->name);
190                 }
191         }
192         
193         virtual ~ModuleChanFilter()
194         {
195                 delete Conf;
196         }
197         
198         virtual Version GetVersion()
199         {
200                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
201         }
202         
203         virtual void OnSyncChannel(chanrec* chan, Module* proto, void* opaque)
204         {
205                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
206                 string_list commands;
207                 if (spamlist)
208                 {
209                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
210                         {
211                                 proto->ProtoSendMode(opaque,TYPE_CHANNEL,chan,"+g "+std::string(i->c_str()));
212                         }
213                 }
214         }
215
216 };
217
218
219 class ModuleChanFilterFactory : public ModuleFactory
220 {
221  public:
222         ModuleChanFilterFactory()
223         {
224         }
225         
226         ~ModuleChanFilterFactory()
227         {
228         }
229         
230         virtual Module * CreateModule(Server* Me)
231         {
232                 return new ModuleChanFilter(Me);
233         }
234         
235 };
236
237
238 extern "C" void * init_module( void )
239 {
240         return new ModuleChanFilterFactory;
241 }
242