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