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