]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_topiclock.cpp
8a0712c3e9a444e65e79e3aa56e235b12efe7332
[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(const std::vector<std::string> &parameters, User *user)
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 = ConvToInt(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 std::vector<std::string>& parameters)
71         {
72                 return ROUTE_BROADCAST;
73         }
74 };
75
76 class FlagExtItem : public ExtensionItem
77 {
78  public:
79         FlagExtItem(const std::string& key, Module* owner)
80                 : ExtensionItem(key, ExtensionItem::EXT_CHANNEL, owner)
81         {
82         }
83
84         bool get(const Extensible* container) const
85         {
86                 return (get_raw(container) != NULL);
87         }
88
89         std::string serialize(SerializeFormat format, const Extensible* container, void* item) const
90         {
91                 if (format == FORMAT_USER)
92                         return "true";
93
94                 return "1";
95         }
96
97         void unserialize(SerializeFormat format, Extensible* container, const std::string& value)
98         {
99                 if (value == "1")
100                         set_raw(container, this);
101                 else
102                         unset_raw(container);
103         }
104
105         void set(Extensible* container, bool value)
106         {
107                 if (value)
108                         set_raw(container, this);
109                 else
110                         unset_raw(container);
111         }
112
113         void unset(Extensible* container)
114         {
115                 unset_raw(container);
116         }
117
118         void free(void* item)
119         {
120                 // nothing to free
121         }
122 };
123
124 class ModuleTopicLock : public Module
125 {
126         CommandSVSTOPIC cmd;
127         FlagExtItem topiclock;
128
129  public:
130         ModuleTopicLock()
131                 : cmd(this), topiclock("topiclock", this)
132         {
133         }
134
135         ModResult OnPreTopicChange(User* user, Channel* chan, const std::string &topic) CXX11_OVERRIDE
136         {
137                 // Only fired for local users currently, but added a check anyway
138                 if ((IS_LOCAL(user)) && (topiclock.get(chan)))
139                 {
140                         user->WriteNumeric(ERR_TOPICLOCK, chan->name, "TOPIC cannot be changed due to topic lock being active on the channel");
141                         return MOD_RES_DENY;
142                 }
143
144                 return MOD_RES_PASSTHRU;
145         }
146
147         Version GetVersion() CXX11_OVERRIDE
148         {
149                 return Version("Implements server-side topic locks and the server-to-server command SVSTOPIC", VF_COMMON | VF_VENDOR);
150         }
151 };
152
153 MODULE_INIT(ModuleTopicLock)