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