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