]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_operprefix.cpp
Replace OnAccessCheck with OnPreMode to remove a number of redundant checks
[user/henk/code/inspircd.git] / src / modules / m_operprefix.cpp
1 /*       +------------------------------------+
2  *       | Inspire Internet Relay Chat Daemon |
3  *       +------------------------------------+
4  *
5  *  InspIRCd: (C) 2002-2009 InspIRCd Development Team
6  * See: http://wiki.inspircd.org/Credits
7  *
8  * This program is free but copyrighted software; see
9  *            the file COPYING for details.
10  *
11  * ---------------------------------------------------
12  */
13
14 /*
15  * Originally by Chernov-Phoenix Alexey (Phoenix@RusNet) mailto:phoenix /email address separator/ pravmail.ru
16  */
17
18 /* $ModDesc: Gives opers cmode +y which provides a staff prefix. */
19
20 #include "inspircd.h"
21
22 #define OPERPREFIX_VALUE 1000000
23
24 class OperPrefixMode : public ModeHandler
25 {
26         public:
27                 OperPrefixMode(InspIRCd* Instance, Module* Creator, char pfx) : ModeHandler(Instance, Creator, 'y', 1, 1, true, MODETYPE_CHANNEL, false, pfx, pfx, TR_NICK) { }
28
29                 unsigned int GetPrefixRank()
30                 {
31                         return OPERPREFIX_VALUE;
32                 }
33
34                 ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
35                 {
36                         if (IS_FAKE(source) || (source && ServerInstance->ULine(source->server)))
37                                 return MODEACTION_ALLOW;
38                         else
39                         {
40                                 if (source && channel)
41                                         source->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only servers are permitted to change channel mode '%c'", source->nick.c_str(), channel->name.c_str(), 'y');
42                                 return MODEACTION_DENY;
43                         }
44                 }
45
46                 ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string &parameter)
47                 {
48                         User* x = ServerInstance->FindNick(parameter);
49                         Membership* m = channel->GetUser(x);
50                         if (x)
51                         {
52                                 if (!m)
53                                 {
54                                         return std::make_pair(false, parameter);
55                                 }
56                                 else
57                                 {
58                                         if (m->hasMode('y'))
59                                                 return std::make_pair(true, x->nick);
60                                         else
61                                                         return std::make_pair(false, parameter);
62                                 }
63                         }
64                         return std::make_pair(false, parameter);
65                 }
66
67                 bool NeedsOper() { return true; }
68 };
69
70 class ModuleOperPrefixMode : public Module
71 {
72  private:
73         OperPrefixMode* opm;
74  public:
75         ModuleOperPrefixMode(InspIRCd* Me) : Module(Me)
76         {
77                 ConfigReader Conf(ServerInstance);
78                 std::string pfx = Conf.ReadValue("operprefix", "prefix", "!", 0, false);
79
80                 opm = new OperPrefixMode(ServerInstance, this, pfx[0]);
81                 if ((!ServerInstance->Modes->AddMode(opm)))
82                         throw ModuleException("Could not add a new mode!");
83
84                 Implementation eventlist[] = { I_OnPostJoin, I_OnUserQuit, I_OnUserKick, I_OnUserPart, I_OnOper };
85                 ServerInstance->Modules->Attach(eventlist, this, 5);
86         }
87
88         void PushChanMode(Channel* channel, User* user)
89         {
90                 char modeline[] = "+y";
91                 std::vector<std::string> modechange;
92                 modechange.push_back(channel->name);
93                 modechange.push_back(modeline);
94                 modechange.push_back(user->nick);
95                 ServerInstance->SendMode(modechange,this->ServerInstance->FakeClient);
96         }
97
98         void OnPostJoin(Membership* memb)
99         {
100                 if (IS_OPER(memb->user) && !memb->user->IsModeSet('H'))
101                         PushChanMode(memb->chan, memb->user);
102         }
103
104         // XXX: is there a better way to do this?
105         ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string &param, bool adding, int pcnt)
106         {
107                 /* force event propagation to its ModeHandler */
108                 if (!IS_FAKE(user) && chan && (mode == 'y'))
109                         return MOD_RES_ALLOW;
110                 return MOD_RES_PASSTHRU;
111         }
112
113         void OnOper(User *user, const std::string&)
114         {
115                 if (user && !user->IsModeSet('H'))
116                 {
117                         for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++)
118                         {
119                                 PushChanMode(*v, user);
120                         }
121                 }
122         }
123
124         ~ModuleOperPrefixMode()
125         {
126                 ServerInstance->Modes->DelMode(opm);
127                 delete opm;
128         }
129
130         Version GetVersion()
131         {
132                 return Version("$Id$", VF_COMMON | VF_VENDOR, API_VERSION);
133         }
134 };
135
136 MODULE_INIT(ModuleOperPrefixMode)