]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/coremods/core_channel/cmd_topic.cpp
ec6ed974490dadc4499eef374a140a9202c19af7
[user/henk/code/inspircd.git] / src / coremods / core_channel / cmd_topic.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
6  *   Copyright (C) 2008 Craig Edwards <craigedwards@brainbox.cc>
7  *   Copyright (C) 2008 Thomas Stagner <aquanight@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 #include "core_channel.h"
25
26 CommandTopic::CommandTopic(Module* parent)
27         : SplitCommand(parent, "TOPIC", 1, 2)
28         , exemptionprov(parent)
29         , secretmode(parent, "secret")
30         , topiclockmode(parent, "topiclock")
31 {
32         syntax = "<channel> [<topic>]";
33         Penalty = 2;
34 }
35
36 CmdResult CommandTopic::HandleLocal(const std::vector<std::string>& parameters, LocalUser* user)
37 {
38         Channel* c = ServerInstance->FindChan(parameters[0]);
39         if (!c)
40         {
41                 user->WriteNumeric(Numerics::NoSuchNick(parameters[0]));
42                 return CMD_FAILURE;
43         }
44
45         if (parameters.size() == 1)
46         {
47                 if ((c->IsModeSet(secretmode)) && (!c->HasUser(user)))
48                 {
49                         user->WriteNumeric(Numerics::NoSuchNick(c->name));
50                         return CMD_FAILURE;
51                 }
52
53                 if (c->topic.length())
54                 {
55                         Topic::ShowTopic(user, c);
56                 }
57                 else
58                 {
59                         user->WriteNumeric(RPL_NOTOPICSET, c->name, "No topic is set.");
60                 }
61                 return CMD_SUCCESS;
62         }
63
64         std::string t = parameters[1]; // needed, in case a module wants to change it
65         ModResult res;
66         FIRST_MOD_RESULT(OnPreTopicChange, res, (user,c,t));
67
68         if (res == MOD_RES_DENY)
69                 return CMD_FAILURE;
70         if (res != MOD_RES_ALLOW)
71         {
72                 if (!c->HasUser(user))
73                 {
74                         user->WriteNumeric(ERR_NOTONCHANNEL, c->name, "You're not on that channel!");
75                         return CMD_FAILURE;
76                 }
77                 if (c->IsModeSet(topiclockmode))
78                 {
79                         ModResult MOD_RESULT;
80                         FIRST_MOD_RESULT_CUSTOM(exemptionprov, CheckExemption::EventListener, OnCheckExemption, MOD_RESULT, (user, c, "topiclock"));
81                         if (!MOD_RESULT.check(c->GetPrefixValue(user) >= HALFOP_VALUE))
82                         {
83                                 user->WriteNumeric(ERR_CHANOPRIVSNEEDED, c->name, "You do not have access to change the topic on this channel");
84                                 return CMD_FAILURE;
85                         }
86                 }
87         }
88
89         // Make sure the topic is not longer than the limit in the config
90         if (t.length() > ServerInstance->Config->Limits.MaxTopic)
91                 t.erase(ServerInstance->Config->Limits.MaxTopic);
92
93         // Only change if the new topic is different than the current one
94         if (c->topic != t)
95                 c->SetTopic(user, t, ServerInstance->Time());
96         return CMD_SUCCESS;
97 }
98
99 void Topic::ShowTopic(LocalUser* user, Channel* chan)
100 {
101         user->WriteNumeric(RPL_TOPIC, chan->name, chan->topic);
102         user->WriteNumeric(RPL_TOPICTIME, chan->name, chan->setby, (unsigned long)chan->topicset);
103 }