]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_censor.cpp
Minor cosmetic fault pointed out by Trystan
[user/henk/code/inspircd.git] / src / modules / m_censor.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 "users.h"
22 #include "channels.h"
23 #include "modules.h"
24 #include "helperfuncs.h"
25
26 /* $ModDesc: Provides user and channel +G mode */
27
28 class ModuleCensor : public Module
29 {
30  Server *Srv;
31  ConfigReader *Conf, *MyConf;
32  
33  public:
34         ModuleCensor(Server* Me)
35                 : Module::Module(Me)
36         {
37                 /*
38                  * read the configuration file on startup.
39                  * it is perfectly valid to set <censor file> to the value of the
40                  * main config file, then append your <badword> tags to the bottom
41                  * of the main config... but rather messy. That's why the capability
42                  * of using a seperate config file is provided.
43                  *
44                  * XXX - Really, it'd be nice to scraip this kind of thing, and have something like
45                  * an include directive to include additional configuration files. Might make our lives easier. --w00t
46                  *
47                  * XXX - These module pre-date the include directive which exists since beta 5 -- Brain
48                  */
49                 Srv = Me;
50                 Conf = new ConfigReader;
51                 std::string Censorfile = Conf->ReadValue("censor","file",0);
52                 MyConf = new ConfigReader(Censorfile);
53                 if ((Censorfile == "") || (!MyConf->Verify()))
54                 {
55                         printf("Error, could not find <censor file=\"\"> definition in your config file!");
56                         log(DEFAULT,"Error, could not find <censor file=\"\"> definition in your config file!");
57                         return;
58                 }
59                 Srv->Log(DEFAULT,std::string("m_censor: read configuration from ")+Censorfile);
60                 Srv->AddExtendedMode('G',MT_CHANNEL,false,0,0);
61                 Srv->AddExtendedMode('G',MT_CLIENT,false,0,0);
62         }
63
64         void Implements(char* List)
65         {
66                 List[I_OnRehash] = List[I_On005Numeric] = List[I_OnUserPreMessage] = List[I_OnUserPreNotice] = List[I_OnExtendedMode] = 1;
67         }
68
69
70         virtual void On005Numeric(std::string &output)
71         {
72                 std::stringstream line(output);
73                 std::string temp1, temp2;
74                 while (!line.eof())
75                 {
76                         line >> temp1;
77                         if (temp1.substr(0,10) == "CHANMODES=")
78                         {
79                                 // append the chanmode to the end
80                                 temp1 = temp1.substr(10,temp1.length());
81                                 temp1 = "CHANMODES=" + temp1 + "G";
82                         }
83                         temp2 = temp2 + temp1 + " ";
84                 }
85                 if (temp2.length())
86                         output = temp2.substr(0,temp2.length()-1);
87         }
88
89
90         virtual int OnExtendedMode(userrec* user, void* target, char modechar, int type, bool mode_on, string_list &params)
91         {
92                 // check if this is our mode character...
93                 if (modechar == 'G')
94                 {
95                         return 1;
96                 }
97                 else
98                 {
99                         return 0;
100                 }
101         }
102         
103         virtual ~ModuleCensor()
104         {
105                 delete MyConf;
106                 delete Conf;
107         }
108         
109         virtual void ReplaceLine(std::string &text,std::string pattern, std::string replace)
110         {
111                 if ((pattern != "") && (text != ""))
112                 {
113                         while (text.find(pattern) != std::string::npos)
114                         {
115                                 int pos = text.find(pattern);
116                                 text.erase(pos,pattern.length());
117                                 text.insert(pos,replace);
118                         }
119                 }
120         }
121         
122         // format of a config entry is <badword text="shit" replace="poo">
123         
124         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text)
125         {
126                 bool active = false;
127                 for (int index = 0; index < MyConf->Enumerate("badword"); index++)
128                 {
129                         std::string pattern = MyConf->ReadValue("badword","text",index);
130                         if (text.find(pattern) != std::string::npos)
131                         {
132                                 std::string replace = MyConf->ReadValue("badword","replace",index);
133
134                                 if (target_type == TYPE_USER)
135                                 {
136                                         userrec* t = (userrec*)dest;
137                                         active = (strchr(t->modes,'G') > 0);
138                                 }
139                                 else if (target_type == TYPE_CHANNEL)
140                                 {
141                                         chanrec* t = (chanrec*)dest;
142                                         active = (t->IsCustomModeSet('G'));
143                                 }
144                                 
145                                 if (active)
146                                 {
147                                         this->ReplaceLine(text,pattern,replace);
148                                 }
149                         }
150                 }
151                 return 0;
152         }
153         
154         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text)
155         {
156                 bool active = false;
157                 for (int index = 0; index < MyConf->Enumerate("badword"); index++)
158                 {
159                         std::string pattern = MyConf->ReadValue("badword","text",index);
160                         if (text.find(pattern) != std::string::npos)
161                         {
162                                 std::string replace = MyConf->ReadValue("badword","replace",index);
163
164                                 if (target_type == TYPE_USER)
165                                 {
166                                         userrec* t = (userrec*)dest;
167                                         active = (strchr(t->modes,'G') > 0);
168                                 }
169                                 else if (target_type == TYPE_CHANNEL)
170                                 {
171                                         chanrec* t = (chanrec*)dest;
172                                         active = (t->IsCustomModeSet('G'));
173                                 }
174                                 
175                                 if (active)
176                                 {
177                                         this->ReplaceLine(text,pattern,replace);
178                                 }
179                         }
180                 }
181                 return 0;
182         }
183         
184         virtual void OnRehash(std::string parameter)
185         {
186                 /*
187                  * reload our config file on rehash - we must destroy and re-allocate the classes
188                  * to call the constructor again and re-read our data.
189                  */
190                 delete Conf;
191                 delete MyConf;
192                 Conf = new ConfigReader;
193                 std::string Censorfile = Conf->ReadValue("censor","file",0);
194                 // this automatically re-reads the configuration file into the class
195                 MyConf = new ConfigReader(Censorfile);
196                 if ((Censorfile == "") || (!MyConf->Verify()))
197                 {
198                         // bail if the user forgot to create a config file
199                         printf("Error, could not find <censor file=\"\"> definition in your config file!\n");
200                         log(DEFAULT,"Error, could not find <censor file=\"\"> definition in your config file!");
201                 }
202                 Srv->Log(DEFAULT,std::string("m_censor: read configuration from ")+Censorfile);
203         }
204         
205         virtual Version GetVersion()
206         {
207                 // This is version 2 because version 1.x is the unreleased unrealircd module
208                 return Version(1,0,0,0,VF_STATIC|VF_VENDOR);
209         }
210         
211 };
212
213 // stuff down here is the module-factory stuff. For basic modules you can ignore this.
214
215 class ModuleCensorFactory : public ModuleFactory
216 {
217  public:
218         ModuleCensorFactory()
219         {
220         }
221         
222         ~ModuleCensorFactory()
223         {
224         }
225         
226         virtual Module * CreateModule(Server* Me)
227         {
228                 return new ModuleCensor(Me);
229         }
230         
231 };
232
233
234 extern "C" void * init_module( void )
235 {
236         return new ModuleCensorFactory;
237 }
238