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

cmode_h.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 #include "inspircd.h"
00015 #include "configreader.h"
00016 #include "mode.h"
00017 #include "channels.h"
00018 #include "users.h"
00019 #include "modules.h"
00020 #include "modes/cmode_h.h"
00021 
00022 ModeChannelHalfOp::ModeChannelHalfOp(InspIRCd* Instance) : ModeHandler(Instance, 'h', 1, 1, true, MODETYPE_CHANNEL, false, '%', '@')
00023 {
00024 }
00025 
00026 unsigned int ModeChannelHalfOp::GetPrefixRank()
00027 {
00028         return HALFOP_VALUE;
00029 }
00030 
00031 ModePair ModeChannelHalfOp::ModeSet(User*, User*, Channel* channel, const std::string &parameter)
00032 {
00033         User* x = ServerInstance->FindNick(parameter);
00034         if (x)
00035         {
00036                 if (channel->GetStatusFlags(x) & UCMODE_HOP)
00037                 {
00038                         return std::make_pair(true, x->nick);
00039                 }
00040                 else
00041                 {
00042                         return std::make_pair(false, parameter);
00043                 }
00044         }
00045         return std::make_pair(false, parameter);
00046 }
00047 
00048 void ModeChannelHalfOp::RemoveMode(Channel* channel, irc::modestacker* stack)
00049 {
00050         CUList* clist = channel->GetHalfoppedUsers();
00051         CUList copy;
00052 
00053         for (CUList::iterator i = clist->begin(); i != clist->end(); i++)
00054         {
00055                 User* n = i->first;
00056                 copy.insert(std::make_pair(n,n->nick));
00057         }
00058 
00059         for (CUList::iterator i = copy.begin(); i != copy.end(); i++)
00060         {
00061                 if (stack)
00062                 {
00063                         stack->Push(this->GetModeChar(), i->first->nick);
00064                 }
00065                 else
00066                 {
00067                         std::vector<std::string> parameters; parameters.push_back(channel->name); parameters.push_back("-h"); parameters.push_back(i->first->nick);
00068                         ServerInstance->SendMode(parameters, ServerInstance->FakeClient);
00069                 }
00070         }
00071 
00072 }
00073 
00074 void ModeChannelHalfOp::RemoveMode(User*, irc::modestacker* stack)
00075 {
00076 }
00077 
00078 ModeAction ModeChannelHalfOp::OnModeChange(User* source, User*, Channel* channel, std::string &parameter, bool adding, bool servermode)
00079 {
00080         /* If halfops are not enabled in the conf, we don't execute
00081          * anything in this class at all.
00082          */
00083         if (!ServerInstance->Config->AllowHalfop)
00084         {
00085                 parameter = "";
00086                 return MODEACTION_DENY;
00087         }
00088 
00089         int status = channel->GetStatus(source);
00090 
00091         /* Call the correct method depending on wether we're adding or removing the mode */
00092         if (adding)
00093         {
00094                 parameter = this->AddHalfOp(source, parameter.c_str(), channel, status);
00095         }
00096         else
00097         {
00098                 parameter = this->DelHalfOp(source, parameter.c_str(), channel, status);
00099         }
00100         /* If the method above 'ate' the parameter by reducing it to an empty string, then
00101          * it won't matter wether we return ALLOW or DENY here, as an empty string overrides
00102          * the return value and is always MODEACTION_DENY if the mode is supposed to have
00103          * a parameter.
00104          */
00105         if (parameter.length())
00106                 return MODEACTION_ALLOW;
00107         else
00108                 return MODEACTION_DENY;
00109 }
00110 
00111 std::string ModeChannelHalfOp::AddHalfOp(User *user,const char* dest,Channel *chan,int status)
00112 {
00113         User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status);
00114 
00115         if (d)
00116         {
00117                 if (IS_LOCAL(user))
00118                 {
00119                         int MOD_RESULT = 0;
00120                         FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_HALFOP));
00121 
00122                         if (MOD_RESULT == ACR_DENY)
00123                                 return "";
00124                         if (MOD_RESULT == ACR_DEFAULT)
00125                         {
00126                                 if ((status < STATUS_OP) && (!ServerInstance->ULine(user->server)))
00127                                 {
00128                                         user->WriteServ("482 %s %s :You're not a channel operator",user->nick.c_str(), chan->name.c_str());
00129                                         return "";
00130                                 }
00131                         }
00132                 }
00133 
00134                 return ServerInstance->Modes->Grant(d,chan,UCMODE_HOP);
00135         }
00136         return "";
00137 }
00138 
00139 std::string ModeChannelHalfOp::DelHalfOp(User *user,const char *dest,Channel *chan,int status)
00140 {
00141         User *d = ServerInstance->Modes->SanityChecks(user,dest,chan,status);
00142 
00143         if (d)
00144         {
00145                 if (IS_LOCAL(user))
00146                 {
00147                         int MOD_RESULT = 0;
00148                         FOREACH_RESULT(I_OnAccessCheck,OnAccessCheck(user,d,chan,AC_DEHALFOP));
00149 
00150                         if (MOD_RESULT == ACR_DENY)
00151                                 return "";
00152                         if (MOD_RESULT == ACR_DEFAULT)
00153                         {
00154                                 if ((user != d) && ((status < STATUS_OP) && (!ServerInstance->ULine(user->server))))
00155                                 {
00156                                         user->WriteServ("482 %s %s :You are not a channel operator",user->nick.c_str(), chan->name.c_str());
00157                                         return "";
00158                                 }
00159                         }
00160                 }
00161 
00162                 return ServerInstance->Modes->Revoke(d,chan,UCMODE_HOP);
00163         }
00164         return "";
00165 }
00166