]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/commands/cmd_invite.cpp
355bde9e6ed0bbef997362945f4ea7842871c9c7
[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         RouteDescriptor GetRouting(User* user, const std::vector<std::string>& parameters)
44         {
45                 return (IS_LOCAL(user) ? ROUTE_LOCALONLY : ROUTE_BROADCAST);
46         }
47 };
48
49 /** Handle /INVITE
50  */
51 CmdResult CommandInvite::Handle (const std::vector<std::string>& parameters, User *user)
52 {
53         ModResult MOD_RESULT;
54
55         if (parameters.size() == 2 || parameters.size() == 3)
56         {
57                 User* u;
58                 if (IS_LOCAL(user))
59                         u = ServerInstance->FindNickOnly(parameters[0]);
60                 else
61                         u = ServerInstance->FindNick(parameters[0]);
62
63                 Channel* c = ServerInstance->FindChan(parameters[1]);
64                 time_t timeout = 0;
65                 if (parameters.size() == 3)
66                 {
67                         if (IS_LOCAL(user))
68                                 timeout = ServerInstance->Time() + InspIRCd::Duration(parameters[1]);
69                         else
70                                 timeout = ConvToInt(parameters[2]);
71                 }
72
73                 if ((!c) || (!u) || (u->registered != REG_ALL))
74                 {
75                         user->WriteNumeric(ERR_NOSUCHNICK, "%s %s :No such nick/channel",user->nick.c_str(), c ? parameters[0].c_str() : parameters[1].c_str());
76                         return CMD_FAILURE;
77                 }
78
79                 if ((IS_LOCAL(user)) && (!c->HasUser(user)))
80                 {
81                         user->WriteNumeric(ERR_NOTONCHANNEL, "%s %s :You're not on that channel!",user->nick.c_str(), c->name.c_str());
82                         return CMD_FAILURE;
83                 }
84
85                 if (c->HasUser(u))
86                 {
87                         user->WriteNumeric(ERR_USERONCHANNEL, "%s %s %s :is already on channel",user->nick.c_str(),u->nick.c_str(),c->name.c_str());
88                         return CMD_FAILURE;
89                 }
90
91                 FIRST_MOD_RESULT(OnUserPreInvite, MOD_RESULT, (user,u,c,timeout));
92
93                 if (MOD_RESULT == MOD_RES_DENY)
94                 {
95                         return CMD_FAILURE;
96                 }
97                 else if (MOD_RESULT == MOD_RES_PASSTHRU)
98                 {
99                         if (IS_LOCAL(user))
100                         {
101                                 unsigned int rank = c->GetPrefixValue(user);
102                                 if (rank < HALFOP_VALUE)
103                                 {
104                                         // Check whether halfop mode is available and phrase error message accordingly
105                                         ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
106                                         user->WriteNumeric(ERR_CHANOPRIVSNEEDED, "%s %s :You must be a channel %soperator",
107                                                 user->nick.c_str(), c->name.c_str(), (mh && mh->name == "halfop" ? "half-" : ""));
108                                         return CMD_FAILURE;
109                                 }
110                         }
111                 }
112
113                 if (IS_LOCAL(u))
114                 {
115                         Invitation::Create(c, IS_LOCAL(u), timeout);
116                         u->WriteFrom(user,"INVITE %s :%s",u->nick.c_str(),c->name.c_str());
117                 }
118
119                 if (IS_LOCAL(user))
120                         user->WriteNumeric(RPL_INVITING, "%s %s %s",user->nick.c_str(),u->nick.c_str(),c->name.c_str());
121
122                 if (ServerInstance->Config->AnnounceInvites != ServerConfig::INVITE_ANNOUNCE_NONE)
123                 {
124                         char prefix;
125                         switch (ServerInstance->Config->AnnounceInvites)
126                         {
127                                 case ServerConfig::INVITE_ANNOUNCE_OPS:
128                                 {
129                                         prefix = '@';
130                                         break;
131                                 }
132                                 case ServerConfig::INVITE_ANNOUNCE_DYNAMIC:
133                                 {
134                                         ModeHandler* mh = ServerInstance->Modes->FindMode('h', MODETYPE_CHANNEL);
135                                         prefix = (mh && mh->name == "halfop" ? mh->GetPrefix() : '@');
136                                         break;
137                                 }
138                                 default:
139                                 {
140                                         prefix = 0;
141                                         break;
142                                 }
143                         }
144                         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());
145                 }
146                 FOREACH_MOD(I_OnUserInvite,OnUserInvite(user,u,c,timeout));
147         }
148         else if (IS_LOCAL(user))
149         {
150                 // pinched from ircu - invite with not enough parameters shows channels
151                 // youve been invited to but haven't joined yet.
152                 InviteList& il = IS_LOCAL(user)->GetInviteList();
153                 for (InviteList::const_iterator i = il.begin(); i != il.end(); ++i)
154                 {
155                         user->WriteNumeric(RPL_INVITELIST, "%s :%s",user->nick.c_str(), (*i)->chan->name.c_str());
156                 }
157                 user->WriteNumeric(RPL_ENDOFINVITELIST, "%s :End of INVITE list",user->nick.c_str());
158         }
159         return CMD_SUCCESS;
160 }
161
162
163 COMMAND_INIT(CommandInvite)