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