The InspIRCd Project
Home | Developers | Wiki | Forums | Bug Tracker | SVN | Download
Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

m_censor.cpp

Go to the documentation of this file.
00001 /*       +------------------------------------+
00002  *       | Inspire Internet Relay Chat Daemon |
00003  *       +------------------------------------+
00004  *
00005  *  InspIRCd: (C) 2002-2008 InspIRCd Development Team
00006  * See: http://www.inspircd.org/wiki/index.php/Credits
00007  *
00008  * This program is free but copyrighted software; see
00009  *            the file COPYING for details.
00010  *
00011  * ---------------------------------------------------
00012  */
00013 
00014 #define _CRT_SECURE_NO_DEPRECATE
00015 #define _SCL_SECURE_NO_DEPRECATE
00016 
00017 #include "inspircd.h"
00018 
00019 typedef std::map<irc::string,irc::string> censor_t;
00020 
00021 /* $ModDesc: Provides user and channel +G mode */
00022 
00025 class CensorUser : public SimpleUserModeHandler
00026 {
00027  public:
00028         CensorUser(InspIRCd* Instance) : SimpleUserModeHandler(Instance, 'G') { }
00029 };
00030 
00033 class CensorChannel : public SimpleChannelModeHandler
00034 {
00035  public:
00036         CensorChannel(InspIRCd* Instance) : SimpleChannelModeHandler(Instance, 'G') { }
00037 };
00038 
00039 class ModuleCensor : public Module
00040 {
00041         censor_t censors;
00042         CensorUser *cu;
00043         CensorChannel *cc;
00044 
00045  public:
00046         ModuleCensor(InspIRCd* Me)
00047                 : Module(Me)
00048         {
00049                 /* Read the configuration file on startup.
00050                  */
00051                 OnRehash(NULL,"");
00052                 cu = new CensorUser(ServerInstance);
00053                 cc = new CensorChannel(ServerInstance);
00054                 if (!ServerInstance->Modes->AddMode(cu) || !ServerInstance->Modes->AddMode(cc))
00055                 {
00056                         delete cu;
00057                         delete cc;
00058                         throw ModuleException("Could not add new modes!");
00059                 }
00060                 Implementation eventlist[] = { I_OnRehash, I_OnUserPreMessage, I_OnUserPreNotice };
00061                 ServerInstance->Modules->Attach(eventlist, this, 3);
00062         }
00063 
00064 
00065         virtual ~ModuleCensor()
00066         {
00067                 ServerInstance->Modes->DelMode(cu);
00068                 ServerInstance->Modes->DelMode(cc);
00069                 delete cu;
00070                 delete cc;
00071         }
00072 
00073         virtual void ReplaceLine(irc::string &text, irc::string pattern, irc::string replace)
00074         {
00075                 if ((!pattern.empty()) && (!text.empty()))
00076                 {
00077                         std::string::size_type pos;
00078                         while ((pos = text.find(pattern)) != irc::string::npos)
00079                         {
00080                                 text.erase(pos,pattern.length());
00081                                 text.insert(pos,replace);
00082                         }
00083                 }
00084         }
00085 
00086         // format of a config entry is <badword text="shit" replace="poo">
00087         virtual int OnUserPreMessage(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
00088         {
00089                 if (!IS_LOCAL(user))
00090                         return 0;
00091 
00092                 bool active = false;
00093 
00094                 if (target_type == TYPE_USER)
00095                         active = ((User*)dest)->IsModeSet('G');
00096                 else if (target_type == TYPE_CHANNEL)
00097                 {
00098                         active = ((Channel*)dest)->IsModeSet('G');
00099                         Channel* c = (Channel*)dest;
00100                         if (CHANOPS_EXEMPT(ServerInstance, 'G') && c->GetStatus(user) == STATUS_OP)
00101                         {
00102                                 return 0;
00103                         }
00104                 }
00105 
00106                 if (!active)
00107                         return 0;
00108 
00109                 irc::string text2 = text.c_str();
00110                 for (censor_t::iterator index = censors.begin(); index != censors.end(); index++)
00111                 {
00112                         if (text2.find(index->first) != irc::string::npos)
00113                         {
00114                                 if (index->second.empty())
00115                                 {
00116                                         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());
00117                                         return 1;
00118                                 }
00119 
00120                                 this->ReplaceLine(text2,index->first,index->second);
00121                         }
00122                 }
00123                 text = text2.c_str();
00124                 return 0;
00125         }
00126 
00127         virtual int OnUserPreNotice(User* user,void* dest,int target_type, std::string &text, char status, CUList &exempt_list)
00128         {
00129                 return OnUserPreMessage(user,dest,target_type,text,status,exempt_list);
00130         }
00131 
00132         virtual void OnRehash(User* user, const std::string &parameter)
00133         {
00134                 /*
00135                  * reload our config file on rehash - we must destroy and re-allocate the classes
00136                  * to call the constructor again and re-read our data.
00137                  */
00138                 ConfigReader* MyConf = new ConfigReader(ServerInstance);
00139                 censors.clear();
00140 
00141                 for (int index = 0; index < MyConf->Enumerate("badword"); index++)
00142                 {
00143                         irc::string pattern = (MyConf->ReadValue("badword","text",index)).c_str();
00144                         irc::string replace = (MyConf->ReadValue("badword","replace",index)).c_str();
00145                         censors[pattern] = replace;
00146                 }
00147 
00148                 delete MyConf;
00149         }
00150 
00151         virtual Version GetVersion()
00152         {
00153                 return Version("$Id: m_censor.cpp 10291 2008-08-25 20:35:51Z w00t $",VF_COMMON|VF_VENDOR,API_VERSION);
00154         }
00155 
00156 };
00157 
00158 MODULE_INIT(ModuleCensor)