]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_sajoin.cpp
62783d9016e7286aa418aa800c2d23bd8d2ffe36
[user/henk/code/inspircd.git] / src / modules / m_sajoin.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013, 2018-2020 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2013 Daniel Vassdal <shutter@canternet.org>
6  *   Copyright (C) 2012-2014, 2016 Attila Molnar <attilamolnar@hush.com>
7  *   Copyright (C) 2012, 2019 Robby <robby@chatbelgie.be>
8  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
9  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
10  *   Copyright (C) 2006 jamie <jamie@e03df62e-2008-0410-955e-edbf42e46eb7>
11  *   Copyright (C) 2005, 2007 Robin Burchell <robin+git@viroteck.net>
12  *   Copyright (C) 2004, 2007, 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
30 /** Handle /SAJOIN
31  */
32 class CommandSajoin : public Command
33 {
34  public:
35         CommandSajoin(Module* Creator) : Command(Creator,"SAJOIN", 1)
36         {
37                 allow_empty_last_param = false;
38                 flags_needed = 'o';
39                 syntax = "[<nick>] <channel>[,<channel>]+";
40                 TRANSLATE2(TR_NICK, TR_TEXT);
41         }
42
43         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
44         {
45                 const unsigned int channelindex = (parameters.size() > 1) ? 1 : 0;
46                 if (CommandParser::LoopCall(user, this, parameters, channelindex))
47                         return CMD_FAILURE;
48
49                 const std::string& channel = parameters[channelindex];
50                 const std::string& nickname = parameters.size() > 1 ? parameters[0] : user->nick;
51
52                 User* dest = ServerInstance->FindNick(nickname);
53                 if ((dest) && (dest->registered == REG_ALL))
54                 {
55                         if (user != dest && !user->HasPrivPermission("users/sajoin-others"))
56                         {
57                                 user->WriteNotice("*** You are not allowed to /SAJOIN other users (the privilege users/sajoin-others is needed to /SAJOIN others).");
58                                 return CMD_FAILURE;
59                         }
60
61                         if (dest->server->IsULine())
62                         {
63                                 user->WriteNumeric(ERR_NOPRIVILEGES, "Cannot use an SA command on a U-lined client");
64                                 return CMD_FAILURE;
65                         }
66                         if (IS_LOCAL(user) && !ServerInstance->IsChannel(channel))
67                         {
68                                 /* we didn't need to check this for each character ;) */
69                                 user->WriteNumeric(ERR_BADCHANMASK, channel, "Invalid channel name");
70                                 return CMD_FAILURE;
71                         }
72
73                         Channel* chan = ServerInstance->FindChan(channel);
74                         if ((chan) && (chan->HasUser(dest)))
75                         {
76                                 user->WriteRemoteNotice("*** " + dest->nick + " is already on " + channel);
77                                 return CMD_FAILURE;
78                         }
79
80                         /* For local users, we call Channel::JoinUser which may create a channel and set its TS.
81                          * For non-local users, we just return CMD_SUCCESS, knowing this will propagate it where it needs to be
82                          * and then that server will handle the command.
83                          */
84                         LocalUser* localuser = IS_LOCAL(dest);
85                         if (localuser)
86                         {
87                                 chan = Channel::JoinUser(localuser, channel, true);
88                                 if (chan)
89                                 {
90                                         ServerInstance->SNO->WriteGlobalSno('a', user->nick+" used SAJOIN to make "+dest->nick+" join "+channel);
91                                         return CMD_SUCCESS;
92                                 }
93                                 else
94                                 {
95                                         user->WriteNotice("*** Could not join "+dest->nick+" to "+channel);
96                                         return CMD_FAILURE;
97                                 }
98                         }
99                         else
100                         {
101                                 return CMD_SUCCESS;
102                         }
103                 }
104                 else
105                 {
106                         user->WriteNotice("*** No such nickname: '" + nickname + "'");
107                         return CMD_FAILURE;
108                 }
109         }
110
111         RouteDescriptor GetRouting(User* user, const Params& parameters) CXX11_OVERRIDE
112         {
113                 return ROUTE_OPT_UCAST(parameters[0]);
114         }
115 };
116
117 class ModuleSajoin : public Module
118 {
119         CommandSajoin cmd;
120  public:
121         ModuleSajoin()
122                 : cmd(this)
123         {
124         }
125
126         Version GetVersion() CXX11_OVERRIDE
127         {
128                 return Version("Adds the /SAJOIN command which allows server operators to force users to join one or more channels.", VF_OPTCOMMON | VF_VENDOR);
129         }
130 };
131
132 MODULE_INIT(ModuleSajoin)