]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_operprefix.cpp
732d588570df7b147563fb7ce58a9d9f603167be
[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(Creator, 'y', PARAM_ALWAYS, MODETYPE_CHANNEL)
28                 {
29                         list = true;
30                         prefix = pfx;
31                         levelrequired = OPERPREFIX_VALUE;
32                         m_paramtype = TR_NICK;
33                 }
34
35                 unsigned int GetPrefixRank()
36                 {
37                         return OPERPREFIX_VALUE;
38                 }
39
40                 ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding)
41                 {
42                         if (IS_FAKE(source) || (source && ServerInstance->ULine(source->server)))
43                                 return MODEACTION_ALLOW;
44                         else
45                         {
46                                 if (source && channel)
47                                         source->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :Only servers are permitted to change channel mode '%c'", source->nick.c_str(), channel->name.c_str(), 'y');
48                                 return MODEACTION_DENY;
49                         }
50                 }
51
52                 ModePair ModeSet(User* source, User* dest, Channel* channel, const std::string &parameter)
53                 {
54                         User* x = ServerInstance->FindNick(parameter);
55                         Membership* m = channel->GetUser(x);
56                         if (x)
57                         {
58                                 if (!m)
59                                 {
60                                         return std::make_pair(false, parameter);
61                                 }
62                                 else
63                                 {
64                                         if (m->hasMode('y'))
65                                                 return std::make_pair(true, x->nick);
66                                         else
67                                                         return std::make_pair(false, parameter);
68                                 }
69                         }
70                         return std::make_pair(false, parameter);
71                 }
72
73                 bool NeedsOper() { return true; }
74 };
75
76 class ModuleOperPrefixMode : public Module
77 {
78  private:
79         OperPrefixMode* opm;
80  public:
81         ModuleOperPrefixMode(InspIRCd* Me) : Module(Me)
82         {
83                 ConfigReader Conf(ServerInstance);
84                 std::string pfx = Conf.ReadValue("operprefix", "prefix", "!", 0, false);
85
86                 opm = new OperPrefixMode(ServerInstance, this, pfx[0]);
87                 if ((!ServerInstance->Modes->AddMode(opm)))
88                         throw ModuleException("Could not add a new mode!");
89
90                 Implementation eventlist[] = { I_OnPostJoin, I_OnUserQuit, I_OnUserKick, I_OnUserPart, I_OnOper };
91                 ServerInstance->Modules->Attach(eventlist, this, 5);
92         }
93
94         void PushChanMode(Channel* channel, User* user)
95         {
96                 char modeline[] = "+y";
97                 std::vector<std::string> modechange;
98                 modechange.push_back(channel->name);
99                 modechange.push_back(modeline);
100                 modechange.push_back(user->nick);
101                 ServerInstance->SendMode(modechange,ServerInstance->FakeClient);
102         }
103
104         void OnPostJoin(Membership* memb)
105         {
106                 if (IS_OPER(memb->user) && !memb->user->IsModeSet('H'))
107                         PushChanMode(memb->chan, memb->user);
108         }
109
110         // XXX: is there a better way to do this?
111         ModResult OnRawMode(User* user, Channel* chan, const char mode, const std::string &param, bool adding, int pcnt)
112         {
113                 /* force event propagation to its ModeHandler */
114                 if (!IS_FAKE(user) && chan && (mode == 'y'))
115                         return MOD_RES_ALLOW;
116                 return MOD_RES_PASSTHRU;
117         }
118
119         void OnOper(User *user, const std::string&)
120         {
121                 if (user && !user->IsModeSet('H'))
122                 {
123                         for (UCListIter v = user->chans.begin(); v != user->chans.end(); v++)
124                         {
125                                 PushChanMode(*v, user);
126                         }
127                 }
128         }
129
130         ~ModuleOperPrefixMode()
131         {
132                 ServerInstance->Modes->DelMode(opm);
133                 delete opm;
134         }
135
136         Version GetVersion()
137         {
138                 return Version("Gives opers cmode +y which provides a staff prefix.", VF_COMMON | VF_VENDOR, API_VERSION);
139         }
140 };
141
142 MODULE_INIT(ModuleOperPrefixMode)