]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_topiclock.cpp
Fix the cloaking module on C++98 compilers.
[user/henk/code/inspircd.git] / src / modules / m_topiclock.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013, 2017-2019 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2012, 2014-2016 Attila Molnar <attilamolnar@hush.com>
6  *
7  * This file is part of InspIRCd.  InspIRCd is free software: you can
8  * redistribute it and/or modify it under the terms of the GNU General Public
9  * License as published by the Free Software Foundation, version 2.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
13  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
14  * details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 #include "inspircd.h"
21
22 enum
23 {
24         // InspIRCd-specific.
25         ERR_TOPICLOCK = 744
26 };
27
28 class CommandSVSTOPIC : public Command
29 {
30  public:
31         CommandSVSTOPIC(Module* Creator)
32                 : Command(Creator, "SVSTOPIC", 1, 4)
33         {
34                 flags_needed = FLAG_SERVERONLY;
35         }
36
37         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
38         {
39                 if (!user->server->IsULine())
40                 {
41                         // Ulines only
42                         return CMD_FAILURE;
43                 }
44
45                 Channel* chan = ServerInstance->FindChan(parameters[0]);
46                 if (!chan)
47                         return CMD_FAILURE;
48
49                 if (parameters.size() == 4)
50                 {
51                         // 4 parameter version, set all topic data on the channel to the ones given in the parameters
52                         time_t topicts = ConvToNum<time_t>(parameters[1]);
53                         if (!topicts)
54                         {
55                                 ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Received SVSTOPIC with a 0 topicts, dropped.");
56                                 return CMD_INVALID;
57                         }
58
59                         chan->SetTopic(user, parameters[3], topicts, &parameters[2]);
60                 }
61                 else
62                 {
63                         // 1 parameter version, nuke the topic
64                         chan->SetTopic(user, std::string(), 0);
65                         chan->setby.clear();
66                 }
67
68                 return CMD_SUCCESS;
69         }
70
71         RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE
72         {
73                 return ROUTE_BROADCAST;
74         }
75 };
76
77 // TODO: add a BoolExtItem to replace this.
78 class FlagExtItem : public ExtensionItem
79 {
80  public:
81         FlagExtItem(const std::string& key, Module* owner)
82                 : ExtensionItem(key, ExtensionItem::EXT_CHANNEL, owner)
83         {
84         }
85
86         bool get(const Extensible* container) const
87         {
88                 return (get_raw(container) != NULL);
89         }
90
91         std::string ToHuman(const Extensible* container, void* item) const CXX11_OVERRIDE
92         {
93                 // Make the human version more readable.
94                 return "true";
95         }
96
97         std::string ToNetwork(const Extensible* container, void* item) const CXX11_OVERRIDE
98         {
99                 return "1";
100         }
101
102         void FromNetwork(Extensible* container, const std::string& value) CXX11_OVERRIDE
103         {
104                 if (value == "1")
105                         set_raw(container, this);
106                 else
107                         unset_raw(container);
108         }
109
110         void set(Extensible* container, bool value)
111         {
112                 if (value)
113                         set_raw(container, this);
114                 else
115                         unset_raw(container);
116         }
117
118         void unset(Extensible* container)
119         {
120                 unset_raw(container);
121         }
122
123         void free(Extensible* container, void* item) CXX11_OVERRIDE
124         {
125                 // nothing to free
126         }
127 };
128
129 class ModuleTopicLock : public Module
130 {
131         CommandSVSTOPIC cmd;
132         FlagExtItem topiclock;
133
134  public:
135         ModuleTopicLock()
136                 : cmd(this), topiclock("topiclock", this)
137         {
138         }
139
140         ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic) CXX11_OVERRIDE
141         {
142                 // Only fired for local users currently, but added a check anyway
143                 if ((IS_LOCAL(user)) && (topiclock.get(chan)))
144                 {
145                         user->WriteNumeric(ERR_TOPICLOCK, chan->name, "TOPIC cannot be changed due to topic lock being active on the channel");
146                         return MOD_RES_DENY;
147                 }
148
149                 return MOD_RES_PASSTHRU;
150         }
151
152         Version GetVersion() CXX11_OVERRIDE
153         {
154                 return Version("Allows services to lock the channel topic so that it can not be changed.", VF_COMMON | VF_VENDOR);
155         }
156 };
157
158 MODULE_INIT(ModuleTopicLock)