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