]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_censor.cpp
Remove <censor file> directive, we've had <include> for years now, make use of it.
[user/henk/code/inspircd.git] / src / modules / m_censor.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 "users.h"
22 #include "channels.h"
23 #include "modules.h"
24 #include "inspircd.h"
25
26 typedef std::map<irc::string,irc::string> censor_t;
27
28 /* $ModDesc: Provides user and channel +G mode */
29
30 /** Handles usermode +G
31  */
32 class CensorUser : public ModeHandler
33 {
34  public:
35         CensorUser(InspIRCd* Instance) : ModeHandler(Instance, 'G', 0, 0, false, MODETYPE_USER, false) { }
36
37         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
38         {
39                 /* Only opers can change other users modes */
40                 if ((source != dest) && (!*source->oper))
41                         return MODEACTION_DENY;
42
43                 if (adding)
44                 {
45                         if (!dest->IsModeSet('G'))
46                         {
47                                 dest->SetMode('G',true);
48                                 return MODEACTION_ALLOW;
49                         }
50                 }
51                 else
52                 {
53                         if (dest->IsModeSet('G'))
54                         {
55                                 dest->SetMode('G',false);
56                                 return MODEACTION_ALLOW;
57                         }
58                 }
59
60                 return MODEACTION_DENY;
61         }
62 };
63
64 /** Handles channel mode +G
65  */
66 class CensorChannel : public ModeHandler
67 {
68  public:
69         CensorChannel(InspIRCd* Instance) : ModeHandler(Instance, 'G', 0, 0, false, MODETYPE_CHANNEL, false) { }
70
71         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
72         {
73                 if (adding)
74                 {
75                         if (!channel->IsModeSet('G'))
76                         {
77                                 channel->SetMode('G',false);
78                                 return MODEACTION_ALLOW;
79                         }
80                 }
81                 else
82                 {
83                         if (channel->IsModeSet('G'))
84                         {
85                                 channel->SetMode('G',false);
86                                 return MODEACTION_ALLOW;
87                         }
88                 }
89
90                 return MODEACTION_ALLOW;
91         }
92 };
93
94 class ModuleCensor : public Module
95 {
96
97         
98         censor_t censors;
99         CensorUser *cu;
100         CensorChannel *cc;
101  
102  public:
103         ModuleCensor(InspIRCd* Me)
104                 : Module::Module(Me)
105         {
106                 /* Read the configuration file on startup.
107                  */
108                 OnRehash("");
109                 cu = new CensorUser(ServerInstance);
110                 cc = new CensorChannel(ServerInstance);
111                 ServerInstance->AddMode(cu, 'G');
112                 ServerInstance->AddMode(cc, 'G');
113         }
114
115         void Implements(char* List)
116         {
117                 List[I_OnRehash] = List[I_OnUserPreMessage] = List[I_OnUserPreNotice] = 1;
118         }
119
120         virtual ~ModuleCensor()
121         {
122                 ServerInstance->Modes->DelMode(cu);
123                 ServerInstance->Modes->DelMode(cc);
124                 DELETE(cu);
125                 DELETE(cc);
126         }
127
128         virtual void ReplaceLine(irc::string &text, irc::string pattern, irc::string replace)
129         {
130                 if ((pattern != "") && (text != ""))
131                 {
132                         while (text.find(pattern) != irc::string::npos)
133                         {
134                                 int pos = text.find(pattern);
135                                 text.erase(pos,pattern.length());
136                                 text.insert(pos,replace);
137                         }
138                 }
139         }
140
141         // format of a config entry is <badword text="shit" replace="poo">
142         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text, char status)
143         {
144                 bool active = false;
145                 irc::string text2 = text.c_str();
146                 for (censor_t::iterator index = censors.begin(); index != censors.end(); index++)
147                 { 
148                         if (text2.find(index->first) != irc::string::npos)
149                         {
150                                 if (target_type == TYPE_USER)
151                                 {
152                                         userrec* t = (userrec*)dest;
153                                         active = t->IsModeSet('G');
154                                 }
155                                 else if (target_type == TYPE_CHANNEL)
156                                 {
157                                         chanrec* t = (chanrec*)dest;
158                                         active = t->IsModeSet('G');
159                                 }
160                                 
161                                 if (active)
162                                 {
163                                         this->ReplaceLine(text2,index->first,index->second);
164                                         text = text2.c_str();
165                                 }
166                         }
167                 }
168                 return 0;
169         }
170         
171         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text, char status)
172         {
173                 return OnUserPreMessage(user,dest,target_type,text,status);
174         }
175         
176         virtual void OnRehash(const std::string &parameter)
177         {
178                 /*
179                  * reload our config file on rehash - we must destroy and re-allocate the classes
180                  * to call the constructor again and re-read our data.
181                  */
182                 ConfigReader* MyConf = new ConfigReader(ServerInstance);
183                 censors.clear();
184                 for (int index = 0; index < MyConf->Enumerate("badword"); index++)
185                 {
186                         irc::string pattern = (MyConf->ReadValue("badword","text",index)).c_str();
187                         irc::string replace = (MyConf->ReadValue("badword","replace",index)).c_str();
188                         censors[pattern] = replace;
189                 }
190                 DELETE(MyConf);
191         }
192         
193         virtual Version GetVersion()
194         {
195                 return Version(1,1,0,0,VF_COMMON|VF_VENDOR,API_VERSION);
196         }
197         
198 };
199
200 // stuff down here is the module-factory stuff. For basic modules you can ignore this.
201
202 class ModuleCensorFactory : public ModuleFactory
203 {
204  public:
205         ModuleCensorFactory()
206         {
207         }
208         
209         ~ModuleCensorFactory()
210         {
211         }
212         
213         virtual Module * CreateModule(InspIRCd* Me)
214         {
215                 return new ModuleCensor(Me);
216         }
217         
218 };
219
220
221 extern "C" void * init_module( void )
222 {
223         return new ModuleCensorFactory;
224 }