]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_chanfilter.cpp
3db636b3577e1736a82651015e438df99dea1c2f
[user/henk/code/inspircd.git] / src / modules / m_chanfilter.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  Inspire is copyright (C) 2002-2004 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
27 /* $ModDesc: Provides channel-specific censor lists (like mode +G but varies from channel to channel) */
28
29 typedef std::vector<std::string> SpamList;
30
31 class ModuleChanFilter : public Module
32 {
33         Server *Srv;
34         ConfigReader *Conf;
35         long MaxEntries;
36         
37  public:
38  
39         ModuleChanFilter()
40         {
41                 Srv = new Server;
42                 Conf = new ConfigReader;
43                 Srv->AddExtendedListMode('g');
44                 MaxEntries = Conf->ReadInteger("chanfilter","maxsize",0,true);
45         }
46         
47         virtual void On005Numeric(std::string &output)
48         {
49                 std::stringstream line(output);
50                 std::string temp1, temp2;
51                 while (!line.eof())
52                 {
53                         line >> temp1;
54                         if (temp1.substr(0,10) == "CHANMODES=")
55                         {
56                                 // append the chanmode to the end
57                                 temp1 = temp1.substr(10,temp1.length());
58                                 temp1 = "CHANMODES=g" + temp1;
59                         }
60                         temp2 = temp2 + temp1 + " ";
61                 }
62                 if (temp2.length())
63                         output = temp2.substr(0,temp2.length()-1);
64         }
65
66         virtual void OnUserPart(userrec* user, chanrec* channel)
67         {
68                 // when the last user parts, delete the list
69                 if (Srv->CountUsers(channel) == 1)
70                 {
71                         SpamList* spamlist = (SpamList*)channel->GetExt("spam_list");
72                         if (spamlist)
73                         {
74                                 channel->Shrink("spam_list");
75                                 delete spamlist;
76                         }
77                 }
78         }
79
80         virtual void OnRehash(std::string parameter)
81         {
82                 delete Conf;
83                 Conf = new ConfigReader;
84                 // re-read our config options on a rehash
85                 MaxEntries = Conf->ReadInteger("chanfilter","maxsize",0,true);
86         }
87
88         virtual int ProcessMessages(userrec* user,chanrec* chan,std::string &text)
89         {
90                 char buffer[MAXBUF];
91                 strlcpy(buffer,text.c_str(),MAXBUF);
92                 for (unsigned int j = 0; j < strlen(buffer); j++)
93                         buffer[j] = tolower(buffer[j]);
94                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
95                 if (spamlist)
96                 {
97                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
98                         {
99                                 if (strstr(text.c_str(),i->c_str()))
100                                 {
101                                         WriteServ(user->fd,"936 %s %s :Your message contained a censored word, and was blocked",user->nick, chan->name);
102                                         return 1;
103                                 }
104                         }
105                 }
106                 return 0;
107         }
108
109         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text)
110         {
111                 if (target_type == TYPE_CHANNEL)
112                 {
113                         return ProcessMessages(user,(chanrec*)dest,text);
114                 }
115                 else return 0;
116         }
117
118         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text)
119         {
120                 if (target_type == TYPE_CHANNEL)
121                 {
122                         return ProcessMessages(user,(chanrec*)dest,text);
123                 }
124                 else return 0;
125         }
126         
127         virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
128         {
129                 if ((modechar == 'g') && (type == MT_CHANNEL))
130                 {
131                         chanrec* chan = (chanrec*)target;
132
133                         for (unsigned int j = 0; j < params[0].length(); j++)
134                                 params[0][j] = tolower(params[0][j]);
135
136                         std::string param = params[0];
137                 
138                         if (mode_on)
139                         {
140                                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
141                                 if (!spamlist)
142                                 {
143                                         spamlist = new SpamList;
144                                         chan->Extend("spam_list",(char*)spamlist);
145                                 }
146                                 if (spamlist->size() < (unsigned)MaxEntries)
147                                 {
148                                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
149                                         {
150                                                 if (*i == params[0])
151                                                 {
152                                                         WriteServ(user->fd,"937 %s %s :The word %s is already on the spamfilter list",user->nick, chan->name,params[0].c_str());
153                                                         return -1;
154                                                 }
155                                         }
156                                         spamlist->push_back(params[0]);
157                                         return 1;
158                                 }
159                                 WriteServ(user->fd,"939 %s %s :Channel spamfilter list is full",user->nick, chan->name);
160                                 return -1;
161                         }
162                         else
163                         {
164                                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
165                                 if (spamlist)
166                                 {
167                                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
168                                         {
169                                                 if (*i == params[0])
170                                                 {
171                                                         spamlist->erase(i);
172                                                         return 1;
173                                                 }
174                                         }
175                                 }
176                                 WriteServ(user->fd,"938 %s %s :No such spamfilter word is set",user->nick, chan->name);
177                                 return -1;
178                         }
179                         return -1;
180                 }       
181                 return 0;
182         }
183
184         virtual void OnSendList(userrec* user, chanrec* channel, char mode)
185         {
186                 if (mode == 'g')
187                 {
188                         SpamList* spamlist = (SpamList*)channel->GetExt("spam_list");
189                         if (spamlist)
190                         {
191                                 for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
192                                 {
193                                         WriteServ(user->fd,"941 %s %s %s",user->nick, channel->name,i->c_str());
194                                 }
195                         }
196                         WriteServ(user->fd,"940 %s %s :End of channel spamfilter list",user->nick, channel->name);
197                 }
198         }
199         
200         virtual ~ModuleChanFilter()
201         {
202                 delete Conf;
203                 delete Srv;
204         }
205         
206         virtual Version GetVersion()
207         {
208                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
209         }
210         
211         virtual void OnSyncChannel(chanrec* chan, Module* proto, void* opaque)
212         {
213                 SpamList* spamlist = (SpamList*)chan->GetExt("spam_list");
214                 string_list commands;
215                 if (spamlist)
216                 {
217                         for (SpamList::iterator i = spamlist->begin(); i != spamlist->end(); i++)
218                         {
219                                 proto->ProtoSendMode(opaque,TYPE_CHANNEL,chan,"+g "+*i);
220                         }
221                 }
222                 return commands;
223         }
224
225 };
226
227
228 class ModuleChanFilterFactory : public ModuleFactory
229 {
230  public:
231         ModuleChanFilterFactory()
232         {
233         }
234         
235         ~ModuleChanFilterFactory()
236         {
237         }
238         
239         virtual Module * CreateModule()
240         {
241                 return new ModuleChanFilter;
242         }
243         
244 };
245
246
247 extern "C" void * init_module( void )
248 {
249         return new ModuleChanFilterFactory;
250 }
251