]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_censor.cpp
More conversions
[user/henk/code/inspircd.git] / src / modules / m_censor.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2007 InspIRCd Development Team
6  * See: http://www.inspircd.org/wiki/index.php/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 #define _CRT_SECURE_NO_DEPRECATE
15 #define _SCL_SECURE_NO_DEPRECATE
16
17 #include "inspircd.h"
18 #include "users.h"
19 #include "channels.h"
20 #include "modules.h"
21
22 typedef std::map<irc::string,irc::string> censor_t;
23
24 /* $ModDesc: Provides user and channel +G mode */
25
26 /** Handles usermode +G
27  */
28 class CensorUser : public ModeHandler
29 {
30  public:
31         CensorUser(InspIRCd* Instance) : ModeHandler(Instance, 'G', 0, 0, false, MODETYPE_USER, false) { }
32
33         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
34         {
35                 if (adding)
36                 {
37                         if (!dest->IsModeSet('G'))
38                         {
39                                 dest->SetMode('G',true);
40                                 return MODEACTION_ALLOW;
41                         }
42                 }
43                 else
44                 {
45                         if (dest->IsModeSet('G'))
46                         {
47                                 dest->SetMode('G',false);
48                                 return MODEACTION_ALLOW;
49                         }
50                 }
51
52                 return MODEACTION_DENY;
53         }
54 };
55
56 /** Handles channel mode +G
57  */
58 class CensorChannel : public ModeHandler
59 {
60  public:
61         CensorChannel(InspIRCd* Instance) : ModeHandler(Instance, 'G', 0, 0, false, MODETYPE_CHANNEL, false) { }
62
63         ModeAction OnModeChange(userrec* source, userrec* dest, chanrec* channel, std::string &parameter, bool adding)
64         {
65                 if (adding)
66                 {
67                         if (!channel->IsModeSet('G'))
68                         {
69                                 channel->SetMode('G',true);
70                                 return MODEACTION_ALLOW;
71                         }
72                 }
73                 else
74                 {
75                         if (channel->IsModeSet('G'))
76                         {
77                                 channel->SetMode('G',false);
78                                 return MODEACTION_ALLOW;
79                         }
80                 }
81
82                 return MODEACTION_ALLOW;
83         }
84 };
85
86 class ModuleCensor : public Module
87 {
88
89         
90         censor_t censors;
91         CensorUser *cu;
92         CensorChannel *cc;
93  
94  public:
95         ModuleCensor(InspIRCd* Me)
96                 : Module(Me)
97         {
98                 /* Read the configuration file on startup.
99                  */
100                 OnRehash(NULL,"");
101                 cu = new CensorUser(ServerInstance);
102                 cc = new CensorChannel(ServerInstance);
103                 if (!ServerInstance->AddMode(cu, 'G') || !ServerInstance->AddMode(cc, 'G'))
104                         throw ModuleException("Could not add new modes!");
105         }
106
107         void Implements(char* List)
108         {
109                 List[I_OnRehash] = List[I_OnUserPreMessage] = List[I_OnUserPreNotice] = 1;
110         }
111
112         virtual ~ModuleCensor()
113         {
114                 ServerInstance->Modes->DelMode(cu);
115                 ServerInstance->Modes->DelMode(cc);
116                 DELETE(cu);
117                 DELETE(cc);
118         }
119
120         virtual void ReplaceLine(irc::string &text, irc::string pattern, irc::string replace)
121         {
122                 if ((!pattern.empty()) && (!text.empty()))
123                 {
124                         std::string::size_type pos;
125                         while ((pos = text.find(pattern)) != irc::string::npos)
126                         {
127                                 text.erase(pos,pattern.length());
128                                 text.insert(pos,replace);
129                         }
130                 }
131         }
132
133         // format of a config entry is <badword text="shit" replace="poo">
134         virtual int OnUserPreMessage(userrec* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
135         {
136                 if (!IS_LOCAL(user))
137                         return 0;
138
139                 bool active = false;
140
141                 if (target_type == TYPE_USER)
142                         active = ((userrec*)dest)->IsModeSet('G');
143                 else if (target_type == TYPE_CHANNEL)
144                         active = ((chanrec*)dest)->IsModeSet('G');
145
146                 if (!active)
147                         return 0;
148
149                 irc::string text2 = text.c_str();
150                 for (censor_t::iterator index = censors.begin(); index != censors.end(); index++)
151                 { 
152                         if (text2.find(index->first) != irc::string::npos)
153                         {
154                                 if (index->second.empty())
155                                 {
156                                         user->WriteServ("936 %s %s %s :Your message contained a censored word, and was blocked", user->nick, ((chanrec*)dest)->name, index->first.c_str());
157                                         return 1;
158                                 }
159                                 
160                                 this->ReplaceLine(text2,index->first,index->second);
161                         }
162                 }
163                 text = text2.c_str();
164                 return 0;
165         }
166         
167         virtual int OnUserPreNotice(userrec* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
168         {
169                 return OnUserPreMessage(user,dest,target_type,text,status,exempt_list);
170         }
171         
172         virtual void OnRehash(userrec* user, const std::string &parameter)
173         {
174                 /*
175                  * reload our config file on rehash - we must destroy and re-allocate the classes
176                  * to call the constructor again and re-read our data.
177                  */
178                 ConfigReader* MyConf = new ConfigReader(ServerInstance);
179                 censors.clear();
180                 for (int index = 0; index < MyConf->Enumerate("badword"); index++)
181                 {
182                         irc::string pattern = (MyConf->ReadValue("badword","text",index)).c_str();
183                         irc::string replace = (MyConf->ReadValue("badword","replace",index)).c_str();
184                         censors[pattern] = replace;
185                 }
186                 DELETE(MyConf);
187         }
188         
189         virtual Version GetVersion()
190         {
191                 return Version(1,1,0,0,VF_COMMON|VF_VENDOR,API_VERSION);
192         }
193         
194 };
195
196 MODULE_INIT(ModuleCensor);