]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modules/m_samode.cpp
Fix the cloaking module on C++98 compilers.
[user/henk/code/inspircd.git] / src / modules / m_samode.cpp
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013, 2017-2020 Sadie Powell <sadie@witchery.services>
5  *   Copyright (C) 2013 Daniel Vassdal <shutter@canternet.org>
6  *   Copyright (C) 2012-2016, 2018 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 Robin Burchell <robin+git@viroteck.net>
10  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
11  *   Copyright (C) 2004, 2006, 2010 Craig Edwards <brain@inspircd.org>
12  *
13  * This file is part of InspIRCd.  InspIRCd is free software: you can
14  * redistribute it and/or modify it under the terms of the GNU General Public
15  * License as published by the Free Software Foundation, version 2.
16  *
17  * This program is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
20  * details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26
27 #include "inspircd.h"
28
29 /** Handle /SAMODE
30  */
31 class CommandSamode : public Command
32 {
33         bool logged;
34
35  public:
36         bool active;
37         CommandSamode(Module* Creator) : Command(Creator,"SAMODE", 2)
38         {
39                 allow_empty_last_param = false;
40                 flags_needed = 'o';
41                 syntax = "<target> (+|-)<modes> [<mode-parameters>]";
42                 active = false;
43         }
44
45         CmdResult Handle(User* user, const Params& parameters) CXX11_OVERRIDE
46         {
47                 if (parameters[0].c_str()[0] != '#')
48                 {
49                         User* target = ServerInstance->FindNickOnly(parameters[0]);
50                         if ((!target) || (target->registered != REG_ALL))
51                         {
52                                 user->WriteNumeric(Numerics::NoSuchNick(parameters[0]));
53                                 return CMD_FAILURE;
54                         }
55
56                         // Changing the modes of another user requires a special permission
57                         if ((target != user) && (!user->HasPrivPermission("users/samode-usermodes")))
58                         {
59                                 user->WriteNotice("*** You are not allowed to /SAMODE other users (the privilege users/samode-usermodes is needed to /SAMODE others).");
60                                 return CMD_FAILURE;
61                         }
62                 }
63
64                 // XXX: Make ModeParser clear LastParse
65                 Modes::ChangeList emptychangelist;
66                 ServerInstance->Modes->ProcessSingle(ServerInstance->FakeClient, NULL, ServerInstance->FakeClient, emptychangelist);
67
68                 logged = false;
69                 this->active = true;
70                 ServerInstance->Parser.CallHandler("MODE", parameters, user);
71                 this->active = false;
72
73                 if (!logged)
74                 {
75                         // If we haven't logged anything yet then the client queried the list of a listmode
76                         // (e.g. /SAMODE #chan b), which was handled internally by the MODE command handler.
77                         //
78                         // Viewing the modes of a user or a channel could also result in this, but
79                         // that is not possible with /SAMODE because we require at least 2 parameters.
80                         LogUsage(user, stdalgo::string::join(parameters));
81                 }
82
83                 return CMD_SUCCESS;
84         }
85
86         void LogUsage(const User* user, const std::string& text)
87         {
88                 logged = true;
89                 ServerInstance->SNO->WriteGlobalSno('a', user->nick + " used SAMODE: " + text);
90         }
91 };
92
93 class ModuleSaMode : public Module
94 {
95         CommandSamode cmd;
96  public:
97         ModuleSaMode()
98                 : cmd(this)
99         {
100         }
101
102         Version GetVersion() CXX11_OVERRIDE
103         {
104                 return Version("Adds the /SAMODE command which allows server operators to change the modes of a target (channel, user) that they would not otherwise have the privileges to change.", VF_VENDOR);
105         }
106
107         ModResult OnPreMode(User* source, User* dest, Channel* channel, Modes::ChangeList& modes) CXX11_OVERRIDE
108         {
109                 if (cmd.active)
110                         return MOD_RES_ALLOW;
111                 return MOD_RES_PASSTHRU;
112         }
113
114         void OnMode(User* user, User* destuser, Channel* destchan, const Modes::ChangeList& modes, ModeParser::ModeProcessFlag processflags) CXX11_OVERRIDE
115         {
116                 if (!cmd.active)
117                         return;
118
119                 std::string logtext = (destuser ? destuser->nick : destchan->name);
120                 logtext.push_back(' ');
121                 logtext += ClientProtocol::Messages::Mode::ToModeLetters(modes);
122
123                 for (Modes::ChangeList::List::const_iterator i = modes.getlist().begin(); i != modes.getlist().end(); ++i)
124                 {
125                         const Modes::Change& item = *i;
126                         if (!item.param.empty())
127                                 logtext.append(1, ' ').append(item.param);
128                 }
129
130                 cmd.LogUsage(user, logtext);
131         }
132
133         void Prioritize() CXX11_OVERRIDE
134         {
135                 Module* disable = ServerInstance->Modules->Find("m_disable.so");
136                 ServerInstance->Modules->SetPriority(this, I_OnRawMode, PRIORITY_BEFORE, disable);
137
138                 Module *override = ServerInstance->Modules->Find("m_override.so");
139                 ServerInstance->Modules->SetPriority(this, I_OnPreMode, PRIORITY_BEFORE, override);
140         }
141 };
142
143 MODULE_INIT(ModuleSaMode)