]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_topiclock.cpp
b4fc8dedcc3b4aa9b3c631b478df648324d153f7
[user/henk/code/inspircd.git] / src / modules / m_topiclock.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2012 Attila Molnar <attilamolnar@hush.com>
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 #include "inspircd.h"
20
21 enum
22 {
23         // InspIRCd-specific.
24         ERR_TOPICLOCK = 744
25 };
26
27 class CommandSVSTOPIC : public Command
28 {
29  public:
30         CommandSVSTOPIC(Module* Creator)
31                 : Command(Creator, "SVSTOPIC", 1, 4)
32         {
33                 flags_needed = FLAG_SERVERONLY;
34         }
35
36         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
37         {
38                 if (!user->server->IsULine())
39                 {
40                         // Ulines only
41                         return CMD_FAILURE;
42                 }
43
44                 Channel* chan = ServerInstance->FindChan(parameters[0]);
45                 if (!chan)
46                         return CMD_FAILURE;
47
48                 if (parameters.size() == 4)
49                 {
50                         // 4 parameter version, set all topic data on the channel to the ones given in the parameters
51                         time_t topicts = ConvToNum<time_t>(parameters[1]);
52                         if (!topicts)
53                         {
54                                 ServerInstance->Logs->Log(MODNAME, LOG_DEFAULT, "Received SVSTOPIC with a 0 topicts, dropped.");
55                                 return CMD_INVALID;
56                         }
57
58                         chan->SetTopic(user, parameters[3], topicts, &parameters[2]);
59                 }
60                 else
61                 {
62                         // 1 parameter version, nuke the topic
63                         chan->SetTopic(user, std::string(), 0);
64                         chan->setby.clear();
65                 }
66
67                 return CMD_SUCCESS;
68         }
69
70         RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE
71         {
72                 return ROUTE_BROADCAST;
73         }
74 };
75
76 // TODO: add a BoolExtItem to replace this.
77 class FlagExtItem : public ExtensionItem
78 {
79  public:
80         FlagExtItem(const std::string& key, Module* owner)
81                 : ExtensionItem(key, ExtensionItem::EXT_CHANNEL, owner)
82         {
83         }
84
85         bool get(const Extensible* container) const
86         {
87                 return (get_raw(container) != NULL);
88         }
89
90         std::string ToHuman(const Extensible* container, void* item) const CXX11_OVERRIDE
91         {
92                 // Make the human version more readable.
93                 return "true";
94         }
95
96         std::string ToNetwork(const Extensible* container, void* item) const CXX11_OVERRIDE
97         {
98                 return "1";
99         }
100
101         void FromNetwork(Extensible* container, const std::string& value) CXX11_OVERRIDE
102         {
103                 if (value == "1")
104                         set_raw(container, this);
105                 else
106                         unset_raw(container);
107         }
108
109         void set(Extensible* container, bool value)
110         {
111                 if (value)
112                         set_raw(container, this);
113                 else
114                         unset_raw(container);
115         }
116
117         void unset(Extensible* container)
118         {
119                 unset_raw(container);
120         }
121
122         void free(Extensible* container, void* item) CXX11_OVERRIDE
123         {
124                 // nothing to free
125         }
126 };
127
128 class ModuleTopicLock : public Module
129 {
130         CommandSVSTOPIC cmd;
131         FlagExtItem topiclock;
132
133  public:
134         ModuleTopicLock()
135                 : cmd(this), topiclock("topiclock", this)
136         {
137         }
138
139         ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic) CXX11_OVERRIDE
140         {
141                 // Only fired for local users currently, but added a check anyway
142                 if ((IS_LOCAL(user)) && (topiclock.get(chan)))
143                 {
144                         user->WriteNumeric(ERR_TOPICLOCK, chan->name, "TOPIC cannot be changed due to topic lock being active on the channel");
145                         return MOD_RES_DENY;
146                 }
147
148                 return MOD_RES_PASSTHRU;
149         }
150
151         Version GetVersion() CXX11_OVERRIDE
152         {
153                 return Version("Implements server-side topic locks and the server-to-server command SVSTOPIC", VF_COMMON | VF_VENDOR);
154         }
155 };
156
157 MODULE_INIT(ModuleTopicLock)