]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_customprefix.cpp
Merge branch 'insp20' into insp3.
[user/henk/code/inspircd.git] / src / modules / m_customprefix.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2010 Daniel De Graaf <danieldg@inspircd.org>
5  *
6  * This file is part of InspIRCd.  InspIRCd is free software: you can
7  * redistribute it and/or modify it under the terms of the GNU General Public
8  * License as published by the Free Software Foundation, version 2.
9  *
10  * This program is distributed in the hope that it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18
19
20 #include "inspircd.h"
21
22 class CustomPrefixMode : public PrefixMode
23 {
24  public:
25         reference<ConfigTag> tag;
26
27         CustomPrefixMode(Module* parent, const std::string& Name, char Letter, char Prefix, ConfigTag* Tag)
28                 : PrefixMode(parent, Name, Letter, 0, Prefix)
29                 , tag(Tag)
30         {
31                 unsigned long rank = tag->getUInt("rank", 0, 0, UINT_MAX);
32                 unsigned long setrank = tag->getUInt("ranktoset", prefixrank, rank, UINT_MAX);
33                 unsigned long unsetrank = tag->getUInt("ranktounset", setrank, setrank, UINT_MAX);
34                 bool depriv = tag->getBool("depriv", true);
35                 this->Update(rank, setrank, unsetrank, depriv);
36
37                 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Created the %s prefix: letter=%c prefix=%c rank=%u ranktoset=%u ranktounset=%i depriv=%d",
38                         name.c_str(), GetModeChar(), GetPrefix(), GetPrefixRank(), GetLevelRequired(true), GetLevelRequired(false), CanSelfRemove());
39         }
40 };
41
42 class ModuleCustomPrefix : public Module
43 {
44         std::vector<CustomPrefixMode*> modes;
45  public:
46         void init() CXX11_OVERRIDE
47         {
48                 ConfigTagList tags = ServerInstance->Config->ConfTags("customprefix");
49                 for (ConfigIter iter = tags.first; iter != tags.second; ++iter)
50                 {
51                         ConfigTag* tag = iter->second;
52
53                         const std::string name = tag->getString("name");
54                         if (name.empty())
55                                 throw ModuleException("<customprefix:name> must be specified at " + tag->getTagLocation());
56
57                         if (tag->getBool("change"))
58                         {
59                                 ModeHandler* mh = ServerInstance->Modes->FindMode(name, MODETYPE_CHANNEL);
60                                 if (!mh)
61                                         throw ModuleException("<customprefix:change> specified for a nonexistent mode at " + tag->getTagLocation());
62
63                                 PrefixMode* pm = mh->IsPrefixMode();
64                                 if (!pm)
65                                         throw ModuleException("<customprefix:change> specified for a non-prefix mode at " + tag->getTagLocation());
66
67                                 unsigned long rank = tag->getUInt("rank", pm->GetPrefixRank(), 0, UINT_MAX);
68                                 unsigned long setrank = tag->getUInt("ranktoset", pm->GetLevelRequired(true), rank, UINT_MAX);
69                                 unsigned long unsetrank = tag->getUInt("ranktounset", pm->GetLevelRequired(false), setrank, UINT_MAX);
70                                 bool depriv = tag->getBool("depriv", pm->CanSelfRemove());
71                                 pm->Update(rank, setrank, unsetrank, depriv);
72
73                                 ServerInstance->Logs->Log(MODNAME, LOG_DEBUG, "Changed the %s prefix: depriv=%u rank=%u ranktoset=%u ranktounset=%u",
74                                         pm->name.c_str(), pm->CanSelfRemove(), pm->GetPrefixRank(), pm->GetLevelRequired(true), pm->GetLevelRequired(false));
75                                 continue;
76                         }
77
78                         const std::string letter = tag->getString("letter");
79                         if (letter.length() != 1)
80                                 throw ModuleException("<customprefix:letter> must be set to a mode character at " + tag->getTagLocation());
81
82                         const std::string prefix = tag->getString("prefix");
83                         if (prefix.length() != 1)
84                                 throw ModuleException("<customprefix:prefix> must be set to a mode prefix at " + tag->getTagLocation());
85
86                         try
87                         {
88                                 CustomPrefixMode* mh = new CustomPrefixMode(this, name, letter[0], prefix[0], tag);
89                                 modes.push_back(mh);
90                                 ServerInstance->Modules->AddService(*mh);
91                         }
92                         catch (ModuleException& e)
93                         {
94                                 throw ModuleException(e.GetReason() + " (while creating mode from " + tag->getTagLocation() + ")");
95                         }
96                 }
97         }
98
99         ~ModuleCustomPrefix()
100         {
101                 stdalgo::delete_all(modes);
102         }
103
104         Version GetVersion() CXX11_OVERRIDE
105         {
106                 return Version("Provides custom prefix channel modes", VF_VENDOR);
107         }
108 };
109
110 MODULE_INIT(ModuleCustomPrefix)