Anope IRC Services  Version 2.0
cs_kick.cpp
Go to the documentation of this file.
1 /* ChanServ core functions
2  *
3  * (C) 2003-2014 Anope Team
4  * Contact us at team@anope.org
5  *
6  * Please read COPYING and README for further details.
7  *
8  * Based on the original code of Epona by Lara.
9  * Based on the original code of Services by Andy Church.
10  */
11 
12 #include "module.h"
13 
14 class CommandCSKick : public Command
15 {
16  public:
17  CommandCSKick(Module *creator) : Command(creator, "chanserv/kick", 2, 3)
18  {
19  this->SetDesc(_("Kicks a specified nick from a channel"));
20  this->SetSyntax(_("\037channel\037 \037nick\037 [\037reason\037]"));
21  this->SetSyntax(_("\037channel\037 \037mask\037 [\037reason\037]"));
22  }
23 
24  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
25  {
26  const Anope::string &chan = params[0];
27  const Anope::string &target = params[1];
28  Anope::string reason = params.size() > 2 ? params[2] : "Requested";
29 
30  User *u = source.GetUser();
31  ChannelInfo *ci = ChannelInfo::Find(params[0]);
32  Channel *c = Channel::Find(params[0]);
33  User *u2 = User::Find(target, true);
34 
35  if (!c)
36  {
37  source.Reply(CHAN_X_NOT_IN_USE, chan.c_str());
38  return;
39  }
40  else if (!ci)
41  {
42  source.Reply(CHAN_X_NOT_REGISTERED, chan.c_str());
43  return;
44  }
45 
46  unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
47  if (reason.length() > reasonmax)
48  reason = reason.substr(0, reasonmax);
49 
50  AccessGroup u_access = source.AccessFor(ci);
51 
52  if (!u_access.HasPriv("KICK") && !source.HasPriv("chanserv/kick"))
53  source.Reply(ACCESS_DENIED);
54  else if (u2)
55  {
56  AccessGroup u2_access = ci->AccessFor(u2);
57  if (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access && !source.HasPriv("chanserv/kick"))
58  source.Reply(ACCESS_DENIED);
59  else if (u2->IsProtected())
60  source.Reply(ACCESS_DENIED);
61  else if (!c->FindUser(u2))
62  source.Reply(NICK_X_NOT_ON_CHAN, u2->nick.c_str(), c->name.c_str());
63  else
64  {
65  bool override = !u_access.HasPriv("KICK") || (u != u2 && ci->HasExt("PEACE") && u2_access >= u_access);
66  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "for " << u2->nick;
67 
68  if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
69  c->Kick(ci->WhoSends(), u2, "%s (%s)", reason.c_str(), source.GetNick().c_str());
70  else
71  c->Kick(ci->WhoSends(), u2, "%s", reason.c_str());
72  }
73  }
74  else if (u_access.HasPriv("FOUNDER"))
75  {
76  Log(LOG_COMMAND, source, this, ci) << "for " << target;
77 
78  int matched = 0, kicked = 0;
79  for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end;)
80  {
81  ChanUserContainer *uc = it->second;
82  ++it;
83 
84  if (Anope::Match(uc->user->nick, target) || Anope::Match(uc->user->GetDisplayedMask(), target))
85  {
86  ++matched;
87 
88  AccessGroup u2_access = ci->AccessFor(uc->user);
89  if (u != uc->user && ci->HasExt("PEACE") && u2_access >= u_access)
90  continue;
91  else if (uc->user->IsProtected())
92  continue;
93 
94  ++kicked;
95  if (ci->HasExt("SIGNKICK") || (ci->HasExt("SIGNKICK_LEVEL") && !u_access.HasPriv("SIGNKICK")))
96  c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s) (%s)", reason.c_str(), target.c_str(), source.GetNick().c_str());
97  else
98  c->Kick(ci->WhoSends(), uc->user, "%s (Matches %s)", reason.c_str(), target.c_str());
99  }
100  }
101 
102  if (matched)
103  source.Reply(_("Kicked %d/%d users matching %s from %s."), kicked, matched, target.c_str(), c->name.c_str());
104  else
105  source.Reply(_("No users on %s match %s."), c->name.c_str(), target.c_str());
106  }
107  else
108  source.Reply(NICK_X_NOT_IN_USE, target.c_str());
109  }
110 
111  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
112  {
113  this->SendSyntax(source);
114  source.Reply(" ");
115  source.Reply(_("Kicks a specified nick from a channel.\n"
116  " \n"
117  "By default, limited to AOPs or those with level 5 access\n"
118  "and above on the channel. Channel founders may use masks too."));
119  return true;
120  }
121 };
122 
123 class CSKick : public Module
124 {
126 
127  public:
128  CSKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR), commandcskick(this)
129  {
130 
131  }
132 };
133 
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: cs_kick.cpp:24
Definition: hashcomp.h:84
#define CHAN_X_NOT_IN_USE
Definition: language.h:85
#define ACCESS_DENIED
Definition: language.h:73
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: cs_kick.cpp:111
CSKick(const Anope::string &modname, const Anope::string &creator)
Definition: cs_kick.cpp:128
Definition: users.h:34
CommandCSKick commandcskick
Definition: cs_kick.cpp:125
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
Anope::string name
Definition: channels.h:44
bool HasPriv(const Anope::string &priv) const
Definition: access.cpp:384
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
#define NICK_X_NOT_IN_USE
Definition: language.h:80
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
BotInfo * WhoSends() const
Definition: regchannel.cpp:383
bool IsProtected()
Definition: users.cpp:724
size_type length() const
Definition: anope.h:131
Definition: Config.cs:26
CoreExport bool Match(const string &str, const string &mask, bool case_sensitive=false, bool use_regex=false)
Definition: misc.cpp:407
Anope::string GetDisplayedMask() const
Definition: users.cpp:274
CommandCSKick(Module *creator)
Definition: cs_kick.cpp:17
#define anope_override
Definition: services.h:56
#define MODULE_INIT(x)
Definition: modules.h:45
ChanUserList users
Definition: channels.h:56
ChanUserContainer * FindUser(User *u) const
Definition: channels.cpp:173
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
AccessGroup AccessFor(const User *u)
Definition: regchannel.cpp:413
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
Anope::string nick
Definition: users.h:62
bool Kick(BotInfo *bi, User *u, const char *reason=NULL,...)
Definition: channels.cpp:762
static User * Find(const Anope::string &name, bool nick_only=false)
Definition: users.cpp:815
static Channel * Find(const Anope::string &name)
Definition: channels.cpp:920
void SendSyntax(CommandSource &)
Definition: command.cpp:145
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
#define _(x)
Definition: services.h:50
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31
#define NICK_X_NOT_ON_CHAN
Definition: language.h:81