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