]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_knock.cpp
171893fd7238379c3ce576cfc96f64459ba60b51
[user/henk/code/inspircd.git] / src / modules / m_knock.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2004-2006, 2008 Craig Edwards <craigedwards@brainbox.cc>
5  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
6  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
7  *
8  * This file is part of InspIRCd.  InspIRCd is free software: you can
9  * redistribute it and/or modify it under the terms of the GNU General Public
10  * License as published by the Free Software Foundation, version 2.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
19  */
20
21
22 #include "inspircd.h"
23
24 enum
25 {
26         // From UnrealIRCd.
27         ERR_CANNOTKNOCK = 480
28 };
29
30 /** Handles the /KNOCK command
31  */
32 class CommandKnock : public Command
33 {
34         SimpleChannelModeHandler& noknockmode;
35         ChanModeReference inviteonlymode;
36
37  public:
38         bool sendnotice;
39         bool sendnumeric;
40         CommandKnock(Module* Creator, SimpleChannelModeHandler& Noknockmode)
41                 : Command(Creator,"KNOCK", 2, 2)
42                 , noknockmode(Noknockmode)
43                 , inviteonlymode(Creator, "inviteonly")
44         {
45                 syntax = "<channel> <reason>";
46                 Penalty = 5;
47         }
48
49         CmdResult Handle(const std::vector<std::string>& parameters, User* user) CXX11_OVERRIDE
50         {
51                 Channel* c = ServerInstance->FindChan(parameters[0]);
52                 if (!c)
53                 {
54                         user->WriteNumeric(Numerics::NoSuchChannel(parameters[0]));
55                         return CMD_FAILURE;
56                 }
57
58                 if (c->HasUser(user))
59                 {
60                         user->WriteNumeric(ERR_KNOCKONCHAN, c->name, InspIRCd::Format("Can't KNOCK on %s, you are already on that channel.", c->name.c_str()));
61                         return CMD_FAILURE;
62                 }
63
64                 if (c->IsModeSet(noknockmode))
65                 {
66                         user->WriteNumeric(ERR_CANNOTKNOCK, InspIRCd::Format("Can't KNOCK on %s, +K is set.", c->name.c_str()));
67                         return CMD_FAILURE;
68                 }
69
70                 if (!c->IsModeSet(inviteonlymode))
71                 {
72                         user->WriteNumeric(ERR_CHANOPEN, c->name, InspIRCd::Format("Can't KNOCK on %s, channel is not invite only so knocking is pointless!", c->name.c_str()));
73                         return CMD_FAILURE;
74                 }
75
76                 if (sendnotice)
77                         c->WriteNotice(InspIRCd::Format("User %s is KNOCKing on %s (%s)", user->nick.c_str(), c->name.c_str(), parameters[1].c_str()));
78
79                 if (sendnumeric)
80                         c->WriteChannelWithServ(ServerInstance->Config->ServerName, "710 %s %s %s :is KNOCKing: %s", c->name.c_str(), c->name.c_str(), user->GetFullHost().c_str(), parameters[1].c_str());
81
82                 user->WriteNotice("KNOCKing on " + c->name);
83                 return CMD_SUCCESS;
84         }
85
86         RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters) CXX11_OVERRIDE
87         {
88                 return ROUTE_OPT_BCAST;
89         }
90 };
91
92 class ModuleKnock : public Module
93 {
94         SimpleChannelModeHandler kn;
95         CommandKnock cmd;
96
97  public:
98         ModuleKnock()
99                 : kn(this, "noknock", 'K')
100                 , cmd(this, kn)
101         {
102         }
103
104         void ReadConfig(ConfigStatus& status) CXX11_OVERRIDE
105         {
106                 std::string knocknotify = ServerInstance->Config->ConfValue("knock")->getString("notify");
107                 if (stdalgo::string::equalsci(knocknotify, "numeric"))
108                 {
109                         cmd.sendnotice = false;
110                         cmd.sendnumeric = true;
111                 }
112                 else if (stdalgo::string::equalsci(knocknotify, "both"))
113                 {
114                         cmd.sendnotice = true;
115                         cmd.sendnumeric = true;
116                 }
117                 else
118                 {
119                         cmd.sendnotice = true;
120                         cmd.sendnumeric = false;
121                 }
122         }
123
124         Version GetVersion() CXX11_OVERRIDE
125         {
126                 return Version("Provides support for /KNOCK and channel mode +K", VF_OPTCOMMON | VF_VENDOR);
127         }
128 };
129
130 MODULE_INIT(ModuleKnock)