]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_censor.cpp
Change module versions to use a string instead of fixed digits, and use propset ID...
[user/henk/code/inspircd.git] / src / modules / m_censor.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2008 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 SimpleUserModeHandler
26 {
27  public:
28         CensorUser(InspIRCd* Instance) : SimpleUserModeHandler(Instance, 'G') { }
29 };
30
31 /** Handles channel mode +G
32  */
33 class CensorChannel : public SimpleChannelModeHandler
34 {
35  public:
36         CensorChannel(InspIRCd* Instance) : SimpleChannelModeHandler(Instance, 'G') { }
37 };
38
39 class ModuleCensor : public Module
40 {
41         censor_t censors;
42         CensorUser *cu;
43         CensorChannel *cc;
44
45  public:
46         ModuleCensor(InspIRCd* Me)
47                 : Module(Me)
48         {
49                 /* Read the configuration file on startup.
50                  */
51                 OnRehash(NULL,"");
52                 cu = new CensorUser(ServerInstance);
53                 cc = new CensorChannel(ServerInstance);
54                 if (!ServerInstance->Modes->AddMode(cu) || !ServerInstance->Modes->AddMode(cc))
55                 {
56                         delete cu;
57                         delete cc;
58                         throw ModuleException("Could not add new modes!");
59                 }
60                 Implementation eventlist[] = { I_OnRehash, I_OnUserPreMessage, I_OnUserPreNotice };
61                 ServerInstance->Modules->Attach(eventlist, this, 3);
62         }
63
64
65         virtual ~ModuleCensor()
66         {
67                 ServerInstance->Modes->DelMode(cu);
68                 ServerInstance->Modes->DelMode(cc);
69                 delete cu;
70                 delete cc;
71         }
72
73         virtual void ReplaceLine(irc::string &text, irc::string pattern, irc::string replace)
74         {
75                 if ((!pattern.empty()) && (!text.empty()))
76                 {
77                         std::string::size_type pos;
78                         while ((pos = text.find(pattern)) != irc::string::npos)
79                         {
80                                 text.erase(pos,pattern.length());
81                                 text.insert(pos,replace);
82                         }
83                 }
84         }
85
86         // format of a config entry is <badword text="shit" replace="poo">
87         virtual int OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
88         {
89                 if (!IS_LOCAL(user))
90                         return 0;
91
92                 bool active = false;
93
94                 if (target_type == TYPE_USER)
95                         active = ((User*)dest)->IsModeSet('G');
96                 else if (target_type == TYPE_CHANNEL)
97                 {
98                         active = ((Channel*)dest)->IsModeSet('G');
99                         Channel* c = (Channel*)dest;
100                         if (CHANOPS_EXEMPT(ServerInstance, 'G') && c->GetStatus(user) == STATUS_OP)
101                         {
102                                 return 0;
103                         }
104                 }
105
106                 if (!active)
107                         return 0;
108
109                 irc::string text2 = text.c_str();
110                 for (censor_t::iterator index = censors.begin(); index != censors.end(); index++)
111                 {
112                         if (text2.find(index->first) != irc::string::npos)
113                         {
114                                 if (index->second.empty())
115                                 {
116                                         user->WriteNumeric(ERR_WORDFILTERED, "%s %s %s :Your message contained a censored word, and was blocked", user->nick.c_str(), ((Channel*)dest)->name.c_str(), index->first.c_str());
117                                         return 1;
118                                 }
119
120                                 this->ReplaceLine(text2,index->first,index->second);
121                         }
122                 }
123                 text = text2.c_str();
124                 return 0;
125         }
126
127         virtual int OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
128         {
129                 return OnUserPreMessage(user,dest,target_type,text,status,exempt_list);
130         }
131
132         virtual void OnRehash(User* user, const std::string &parameter)
133         {
134                 /*
135                  * reload our config file on rehash - we must destroy and re-allocate the classes
136                  * to call the constructor again and re-read our data.
137                  */
138                 ConfigReader* MyConf = new ConfigReader(ServerInstance);
139                 censors.clear();
140
141                 for (int index = 0; index < MyConf->Enumerate("badword"); index++)
142                 {
143                         irc::string pattern = (MyConf->ReadValue("badword","text",index)).c_str();
144                         irc::string replace = (MyConf->ReadValue("badword","replace",index)).c_str();
145                         censors[pattern] = replace;
146                 }
147
148                 delete MyConf;
149         }
150
151         virtual Version GetVersion()
152         {
153                 return Version("$Id$",VF_COMMON|VF_VENDOR,API_VERSION);
154         }
155
156 };
157
158 MODULE_INIT(ModuleCensor)