]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/coremods/core_channel/cmd_topic.cpp
Fix some confusing logic in sanick.
[user/henk/code/inspircd.git] / src / coremods / core_channel / cmd_topic.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2019 Matt Schatz <genius3000@g3k.solutions>
5  *   Copyright (C) 2017-2018 Sadie Powell <sadie@witchery.services>
6  *   Copyright (C) 2017 B00mX0r <b00mx0r@aureus.pw>
7  *   Copyright (C) 2013-2016 Attila Molnar <attilamolnar@hush.com>
8  *   Copyright (C) 2012, 2019 Robby <robby@chatbelgie.be>
9  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
10  *   Copyright (C) 2008 Robin Burchell <robin+git@viroteck.net>
11  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
12  *   Copyright (C) 2006, 2010 Craig Edwards <brain@inspircd.org>
13  *
14  * This file is part of InspIRCd.  InspIRCd is free software: you can
15  * redistribute it and/or modify it under the terms of the GNU General Public
16  * License as published by the Free Software Foundation, version 2.
17  *
18  * This program is distributed in the hope that it will be useful, but WITHOUT
19  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
20  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
21  * details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
25  */
26
27
28 #include "inspircd.h"
29 #include "core_channel.h"
30
31 CommandTopic::CommandTopic(Module* parent)
32         : SplitCommand(parent, "TOPIC", 1, 2)
33         , exemptionprov(parent)
34         , secretmode(parent, "secret")
35         , topiclockmode(parent, "topiclock")
36 {
37         syntax = "<channel> [:<topic>]";
38         Penalty = 2;
39 }
40
41 CmdResult CommandTopic::HandleLocal(LocalUser* user, const Params& parameters)
42 {
43         Channel* c = ServerInstance->FindChan(parameters[0]);
44         if (!c)
45         {
46                 user->WriteNumeric(Numerics::NoSuchChannel(parameters[0]));
47                 return CMD_FAILURE;
48         }
49
50         if (parameters.size() == 1)
51         {
52                 if ((c->IsModeSet(secretmode)) && (!c->HasUser(user) && !user->HasPrivPermission("channels/auspex")))
53                 {
54                         user->WriteNumeric(Numerics::NoSuchChannel(c->name));
55                         return CMD_FAILURE;
56                 }
57
58                 if (c->topic.length())
59                 {
60                         Topic::ShowTopic(user, c);
61                 }
62                 else
63                 {
64                         user->WriteNumeric(RPL_NOTOPICSET, c->name, "No topic is set.");
65                 }
66                 return CMD_SUCCESS;
67         }
68
69         std::string t = parameters[1]; // needed, in case a module wants to change it
70         ModResult res;
71         FIRST_MOD_RESULT(OnPreTopicChange, res, (user,c,t));
72
73         if (res == MOD_RES_DENY)
74                 return CMD_FAILURE;
75         if (res != MOD_RES_ALLOW)
76         {
77                 if (!c->HasUser(user))
78                 {
79                         user->WriteNumeric(ERR_NOTONCHANNEL, c->name, "You're not on that channel!");
80                         return CMD_FAILURE;
81                 }
82                 if (c->IsModeSet(topiclockmode))
83                 {
84                         ModResult MOD_RESULT = CheckExemption::Call(exemptionprov, user, c, "topiclock");
85                         if (!MOD_RESULT.check(c->GetPrefixValue(user) >= HALFOP_VALUE))
86                         {
87                                 user->WriteNumeric(ERR_CHANOPRIVSNEEDED, c->name, "You do not have access to change the topic on this channel");
88                                 return CMD_FAILURE;
89                         }
90                 }
91         }
92
93         // Make sure the topic is not longer than the limit in the config
94         if (t.length() > ServerInstance->Config->Limits.MaxTopic)
95                 t.erase(ServerInstance->Config->Limits.MaxTopic);
96
97         // Only change if the new topic is different than the current one
98         if (c->topic != t)
99                 c->SetTopic(user, t, ServerInstance->Time());
100         return CMD_SUCCESS;
101 }
102
103 void Topic::ShowTopic(LocalUser* user, Channel* chan)
104 {
105         user->WriteNumeric(RPL_TOPIC, chan->name, chan->topic);
106         user->WriteNumeric(RPL_TOPICTIME, chan->name, chan->setby, (unsigned long)chan->topicset);
107 }