]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands/cmd_invite.cpp
Merge pull request #1018 from SaberUK/insp20+hidekills
[user/henk/code/inspircd.git] / src / commands / cmd_invite.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
25 /** Handle /INVITE. These command handlers can be reloaded by the core,
26  * and handle basic RFC1459 commands. Commands within modules work
27  * the same way, however, they can be fully unloaded, where these
28  * may not.
29  */
30 class CommandInvite : public Command
31 {
32  public:
33         /** Constructor for invite.
34          */
35         CommandInvite ( Module* parent) : Command(parent,"INVITE", 0, 0) { Penalty = 4; syntax = "[<nick> <channel>]"; }
36         /** Handle command.
37          * @param parameters The parameters to the comamnd
38          * @param pcnt The number of parameters passed to teh command
39          * @param user The user issuing the command
40          * @return A value from CmdResult to indicate command success or failure.
41          */
42         CmdResult Handle(const std::vector<std::string>& parameters, User *user);
43 };
44
45 /** Handle /INVITE
46  */
47 CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, User *user)
48 {
49         ModResult MOD_RESULT;
50
51         if (parameters.size() == 2 || parameters.size() == 3)
52         {
53                 User* u;
54                 if (IS_LOCAL(user))
55                         u = ServerInstance->FindNickOnly(parameters[0]);
56                 else
57                         u = ServerInstance->FindNick(parameters[0]);
58
59                 Channel* c = ServerInstance->FindChan(parameters[1]);
60                 time_t timeout = 0;
61                 if (parameters.size() == 3)
62                 {
63                         if (IS_LOCAL(user))
64                                 timeout = ServerInstance->Time() + ServerInstance->Duration(parameters[2]);
65                         else
66                                 timeout = ConvToInt(parameters[2]);
67                 }
68
69                 if ((!c) || (!u) || (u->registered != REG_ALL))
70                 {
71                         user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), c ? parameters[0].c_str() : parameters[1].c_str());
72                         return CMD_FAILURE;
73                 }
74
75                 if ((IS_LOCAL(user)) && (!c->HasUser(user)))
76                 {
77                         user->WriteNumeric(ERR_NOTONCHANNEL, "%s %s :You're not on that channel!",user->nick.c_str(), c->name.c_str());
78                         return CMD_FAILURE;
79                 }
80
81                 if (c->HasUser(u))
82                 {
83                         user->WriteNumeric(ERR_USERONCHANNEL, "%s %s %s :is already on channel",user->nick.c_str(),u->nick.c_str(),c->name.c_str());
84                         return CMD_FAILURE;
85                 }
86
87                 FIRST_MOD_RESULT(OnUserPreInvite, MOD_RESULT, (user,u,c,timeout));
88
89                 if (MOD_RESULT == MOD_RES_DENY)
90                 {
91                         return CMD_FAILURE;
92                 }
93                 else if (MOD_RESULT == MOD_RES_PASSTHRU)
94                 {
95                         if (IS_LOCAL(user))
96                         {
97                                 unsigned int rank = c->GetPrefixValue(user);
98                                 if (rank < HALFOP_VALUE)
99                                 {
100                                         // Check whether halfop mode is available and phrase error message accordingly
101                                         ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
102                                         user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator",
103                                                 user->nick.c_str(), c->name.c_str(), (mh && mh->name == "halfop" ? "half-" : ""));
104                                         return CMD_FAILURE;
105                                 }
106                         }
107                 }
108
109                 if (IS_LOCAL(u))
110                         IS_LOCAL(u)->InviteTo(c->name.c_str(), timeout);
111                 u->WriteFrom(user,"INVITE %s :%s",u->nick.c_str(),c->name.c_str());
112                 user->WriteNumeric(RPL_INVITING, "%s %s %s",user->nick.c_str(),u->nick.c_str(),c->name.c_str());
113                 if (ServerInstance->Config->AnnounceInvites != ServerConfig::INVITE_ANNOUNCE_NONE)
114                 {
115                         char prefix;
116                         switch (ServerInstance->Config->AnnounceInvites)
117                         {
118                                 case ServerConfig::INVITE_ANNOUNCE_OPS:
119                                 {
120                                         prefix = '@';
121                                         break;
122                                 }
123                                 case ServerConfig::INVITE_ANNOUNCE_DYNAMIC:
124                                 {
125                                         ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
126                                         prefix = (mh && mh->name == "halfop" ? mh->GetPrefix() : '@');
127                                         break;
128                                 }
129                                 default:
130                                 {
131                                         prefix = 0;
132                                         break;
133                                 }
134                         }
135                         c->WriteAllExceptSender(user, true, prefix, "NOTICE %s :*** %s invited %s into the channel", c->name.c_str(), user->nick.c_str(), u->nick.c_str());
136                 }
137                 FOREACH_MOD(I_OnUserInvite,OnUserInvite(user,u,c,timeout));
138         }
139         else if (IS_LOCAL(user))
140         {
141                 // pinched from ircu - invite with not enough parameters shows channels
142                 // youve been invited to but haven't joined yet.
143                 InviteList& il = IS_LOCAL(user)->GetInviteList();
144                 for (InviteList::const_iterator i = il.begin(); i != il.end(); ++i)
145                 {
146                         user->WriteNumeric(RPL_INVITELIST, "%s :%s",user->nick.c_str(), (*i)->chan->name.c_str());
147                 }
148                 user->WriteNumeric(RPL_ENDOFINVITELIST, "%s :End of INVITE list",user->nick.c_str());
149         }
150         return CMD_SUCCESS;
151 }
152
153
154 COMMAND_INIT(CommandInvite)