Anope IRC Services  Version 2.0
cs_akick.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 CommandCSAKick : public Command
15 {
16  void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
17  {
18  Anope::string mask = params[2];
19  Anope::string reason = params.size() > 3 ? params[3] : "";
20  const NickAlias *na = NickAlias::Find(mask);
21  NickCore *nc = NULL;
22  const AutoKick *akick;
23  unsigned reasonmax = Config->GetModule("chanserv")->Get<unsigned>("reasonmax", "200");
24 
25  if (reason.length() > reasonmax)
26  reason = reason.substr(0, reasonmax);
27 
28  if (IRCD->IsExtbanValid(mask))
29  ; /* If this is an extban don't try to complete the mask */
30  else if (IRCD->IsChannelValid(mask))
31  {
32  /* Also don't try to complete the mask if this is a channel */
33 
34  if (mask.equals_ci(ci->name) && ci->HasExt("PEACE"))
35  {
36  source.Reply(ACCESS_DENIED);
37  return;
38  }
39  }
40  else if (!na)
41  {
42  /* If the mask contains a realname the reason must be prepended with a : */
43  if (mask.find('#') != Anope::string::npos)
44  {
45  size_t r = reason.find(':');
46  if (r != Anope::string::npos)
47  {
48  mask += " " + reason.substr(0, r);
49  mask.trim();
50  reason = reason.substr(r + 1);
51  reason.trim();
52  }
53  else
54  {
55  mask = mask + " " + reason;
56  reason.clear();
57  }
58  }
59 
60  Entry e("", mask);
61 
62  mask = (e.nick.empty() ? "*" : e.nick) + "!"
63  + (e.user.empty() ? "*" : e.user) + "@"
64  + (e.host.empty() ? "*" : e.host);
65  if (!e.real.empty())
66  mask += "#" + e.real;
67  }
68  else
69  nc = na->nc;
70 
71  /* Check excepts BEFORE we get this far */
72  if (ci->c)
73  {
74  std::pair<Channel::ModeList::iterator, Channel::ModeList::iterator> modes = ci->c->GetModeList("EXCEPT");
75  for (; modes.first != modes.second; ++modes.first)
76  {
77  if (Anope::Match(modes.first->second, mask))
78  {
79  source.Reply(CHAN_EXCEPTED, mask.c_str(), ci->name.c_str());
80  return;
81  }
82  }
83  }
84 
85  bool override = !source.AccessFor(ci).HasPriv("AKICK");
86  /* Opers overriding get to bypass PEACE */
87  if (override)
88  ;
89  /* These peace checks are only for masks */
90  else if (IRCD->IsChannelValid(mask))
91  ;
92  /* Check whether target nick has equal/higher access
93  * or whether the mask matches a user with higher/equal access - Viper */
94  else if (ci->HasExt("PEACE") && nc)
95  {
96  AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
97  if (nc == ci->GetFounder() || nc_access >= u_access)
98  {
99  source.Reply(ACCESS_DENIED);
100  return;
101  }
102  }
103  else if (ci->HasExt("PEACE"))
104  {
105  /* Match against all currently online users with equal or
106  * higher access. - Viper */
107  for (user_map::const_iterator it = UserListByNick.begin(); it != UserListByNick.end(); ++it)
108  {
109  User *u2 = it->second;
110 
111  AccessGroup nc_access = ci->AccessFor(nc), u_access = source.AccessFor(ci);
112  Entry entry_mask("", mask);
113 
114  if ((ci->AccessFor(u2).HasPriv("FOUNDER") || nc_access >= u_access) && entry_mask.Matches(u2))
115  {
116  source.Reply(ACCESS_DENIED);
117  return;
118  }
119  }
120 
121  /* Match against the lastusermask of all nickalias's with equal
122  * or higher access. - Viper */
123  for (nickalias_map::const_iterator it = NickAliasList->begin(), it_end = NickAliasList->end(); it != it_end; ++it)
124  {
125  na = it->second;
126 
127  AccessGroup nc_access = ci->AccessFor(na->nc), u_access = source.AccessFor(ci);
128  if (na->nc && (na->nc == ci->GetFounder() || nc_access >= u_access))
129  {
130  Anope::string buf = na->nick + "!" + na->last_usermask;
131  if (Anope::Match(buf, mask))
132  {
133  source.Reply(ACCESS_DENIED);
134  return;
135  }
136  }
137  }
138  }
139 
140  for (unsigned j = 0, end = ci->GetAkickCount(); j < end; ++j)
141  {
142  akick = ci->GetAkick(j);
143  if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
144  {
145  source.Reply(_("\002%s\002 already exists on %s autokick list."), akick->nc ? akick->nc->display.c_str() : akick->mask.c_str(), ci->name.c_str());
146  return;
147  }
148  }
149 
150  if (ci->GetAkickCount() >= Config->GetModule(this->owner)->Get<unsigned>("autokickmax"))
151  {
152  source.Reply(_("Sorry, you can only have %d autokick masks on a channel."), Config->GetModule(this->owner)->Get<unsigned>("autokickmax"));
153  return;
154  }
155 
156  if (nc)
157  akick = ci->AddAkick(source.GetNick(), nc, reason);
158  else
159  akick = ci->AddAkick(source.GetNick(), mask, reason);
160 
161  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask << (reason == "" ? "" : ": ") << reason;
162 
163  FOREACH_MOD(OnAkickAdd, (source, ci, akick));
164 
165  source.Reply(_("\002%s\002 added to %s autokick list."), mask.c_str(), ci->name.c_str());
166 
167  this->DoEnforce(source, ci);
168  }
169 
170  void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
171  {
172  const Anope::string &mask = params[2];
173  unsigned i, end;
174 
175  if (!ci->GetAkickCount())
176  {
177  source.Reply(_("%s autokick list is empty."), ci->name.c_str());
178  return;
179  }
180 
181  /* Special case: is it a number/list? Only do search if it isn't. */
182  if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
183  {
184  class AkickDelCallback : public NumberList
185  {
186  CommandSource &source;
187  ChannelInfo *ci;
188  Command *c;
189  unsigned deleted;
190  AccessGroup ag;
191  public:
192  AkickDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, const Anope::string &list) : NumberList(list, true), source(_source), ci(_ci), c(_c), deleted(0), ag(source.AccessFor(ci))
193  {
194  }
195 
196  ~AkickDelCallback()
197  {
198  if (!deleted)
199  source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
200  else if (deleted == 1)
201  source.Reply(_("Deleted 1 entry from %s autokick list."), ci->name.c_str());
202  else
203  source.Reply(_("Deleted %d entries from %s autokick list."), deleted, ci->name.c_str());
204  }
205 
206  void HandleNumber(unsigned number) anope_override
207  {
208  if (!number || number > ci->GetAkickCount())
209  return;
210 
211  const AutoKick *akick = ci->GetAkick(number - 1);
212 
213  FOREACH_MOD(OnAkickDel, (source, ci, akick));
214 
215  bool override = !ag.HasPriv("AKICK");
216  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << (akick->nc ? akick->nc->display : akick->mask);
217 
218  ++deleted;
219  ci->EraseAkick(number - 1);
220  }
221  }
222  delcallback(source, ci, this, mask);
223  delcallback.Process();
224  }
225  else
226  {
227  const NickAlias *na = NickAlias::Find(mask);
228  const NickCore *nc = na ? *na->nc : NULL;
229 
230  for (i = 0, end = ci->GetAkickCount(); i < end; ++i)
231  {
232  const AutoKick *akick = ci->GetAkick(i);
233 
234  if (akick->nc ? akick->nc == nc : mask.equals_ci(akick->mask))
235  break;
236  }
237 
238  if (i == ci->GetAkickCount())
239  {
240  source.Reply(_("\002%s\002 not found on %s autokick list."), mask.c_str(), ci->name.c_str());
241  return;
242  }
243 
244  bool override = !source.AccessFor(ci).HasPriv("AKICK");
245  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << mask;
246 
247  FOREACH_MOD(OnAkickDel, (source, ci, ci->GetAkick(i)));
248 
249  ci->EraseAkick(i);
250 
251  source.Reply(_("\002%s\002 deleted from %s autokick list."), mask.c_str(), ci->name.c_str());
252  }
253  }
254 
255  void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params, ListFormatter &list)
256  {
257  const Anope::string &mask = params.size() > 2 ? params[2] : "";
258 
259  if (!mask.empty() && isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
260  {
261  class AkickListCallback : public NumberList
262  {
263  ListFormatter &list;
264  ChannelInfo *ci;
265 
266  public:
267  AkickListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist) : NumberList(numlist, false), list(_list), ci(_ci)
268  {
269  }
270 
271  void HandleNumber(unsigned number) anope_override
272  {
273  if (!number || number > ci->GetAkickCount())
274  return;
275 
276  const AutoKick *akick = ci->GetAkick(number - 1);
277 
278  Anope::string timebuf, lastused;
279  if (akick->addtime)
280  timebuf = Anope::strftime(akick->addtime, NULL, true);
281  else
282  timebuf = UNKNOWN;
283  if (akick->last_used)
284  lastused = Anope::strftime(akick->last_used, NULL, true);
285  else
286  lastused = UNKNOWN;
287 
289  entry["Number"] = stringify(number);
290  if (akick->nc)
291  entry["Mask"] = akick->nc->display;
292  else
293  entry["Mask"] = akick->mask;
294  entry["Creator"] = akick->creator;
295  entry["Created"] = timebuf;
296  entry["Last used"] = lastused;
297  entry["Reason"] = akick->reason;
298  this->list.AddEntry(entry);
299  }
300  }
301  nl_list(list, ci, mask);
302  nl_list.Process();
303  }
304  else
305  {
306  for (unsigned i = 0, end = ci->GetAkickCount(); i < end; ++i)
307  {
308  const AutoKick *akick = ci->GetAkick(i);
309 
310  if (!mask.empty())
311  {
312  if (!akick->nc && !Anope::Match(akick->mask, mask))
313  continue;
314  if (akick->nc && !Anope::Match(akick->nc->display, mask))
315  continue;
316  }
317 
318  Anope::string timebuf, lastused;
319  if (akick->addtime)
320  timebuf = Anope::strftime(akick->addtime, NULL, true);
321  else
322  timebuf = UNKNOWN;
323  if (akick->last_used)
324  lastused = Anope::strftime(akick->last_used, NULL, true);
325  else
326  lastused = UNKNOWN;
327 
329  entry["Number"] = stringify(i + 1);
330  if (akick->nc)
331  entry["Mask"] = akick->nc->display;
332  else
333  entry["Mask"] = akick->mask;
334  entry["Creator"] = akick->creator;
335  entry["Created"] = timebuf;
336  entry["Last used"] = lastused;
337  entry["Reason"] = akick->reason;
338  list.AddEntry(entry);
339  }
340  }
341 
342  if (list.IsEmpty())
343  source.Reply(_("No matching entries on %s autokick list."), ci->name.c_str());
344  else
345  {
346  std::vector<Anope::string> replies;
347  list.Process(replies);
348 
349  source.Reply(_("Autokick list for %s:"), ci->name.c_str());
350 
351  for (unsigned i = 0; i < replies.size(); ++i)
352  source.Reply(replies[i]);
353 
354  source.Reply(_("End of autokick list"));
355  }
356  }
357 
358  void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
359  {
360  if (!ci->GetAkickCount())
361  {
362  source.Reply(_("%s autokick list is empty."), ci->name.c_str());
363  return;
364  }
365 
366  ListFormatter list(source.GetAccount());
367  list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Reason"));
368  this->ProcessList(source, ci, params, list);
369  }
370 
371  void DoView(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
372  {
373  if (!ci->GetAkickCount())
374  {
375  source.Reply(_("%s autokick list is empty."), ci->name.c_str());
376  return;
377  }
378 
379  ListFormatter list(source.GetAccount());
380  list.AddColumn(_("Number")).AddColumn(_("Mask")).AddColumn(_("Creator")).AddColumn(_("Created")).AddColumn(_("Last used")).AddColumn(_("Reason"));
381  this->ProcessList(source, ci, params, list);
382  }
383 
385  {
386  Channel *c = ci->c;
387  int count = 0;
388 
389  if (!c)
390  {
391  source.Reply(CHAN_X_NOT_IN_USE, ci->name.c_str());
392  return;
393  }
394 
395  for (Channel::ChanUserList::iterator it = c->users.begin(), it_end = c->users.end(); it != it_end; )
396  {
397  ChanUserContainer *uc = it->second;
398  ++it;
399 
400  if (c->CheckKick(uc->user))
401  ++count;
402  }
403 
404  bool override = !source.AccessFor(ci).HasPriv("AKICK");
405  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "ENFORCE, affects " << count << " users";
406 
407  source.Reply(_("AKICK ENFORCE for \002%s\002 complete; \002%d\002 users were affected."), ci->name.c_str(), count);
408  }
409 
411  {
412  bool override = !source.AccessFor(ci).HasPriv("AKICK");
413  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the akick list";
414 
415  ci->ClearAkick();
416  source.Reply(_("Channel %s akick list has been cleared."), ci->name.c_str());
417  }
418 
419  public:
420  CommandCSAKick(Module *creator) : Command(creator, "chanserv/akick", 2, 4)
421  {
422  this->SetDesc(_("Maintain the AutoKick list"));
423  this->SetSyntax(_("\037channel\037 ADD {\037nick\037 | \037mask\037} [\037reason\037]"));
424  this->SetSyntax(_("\037channel\037 DEL {\037nick\037 | \037mask\037 | \037entry-num\037 | \037list\037}"));
425  this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037entry-num\037 | \037list\037]"));
426  this->SetSyntax(_("\037channel\037 VIEW [\037mask\037 | \037entry-num\037 | \037list\037]"));
427  this->SetSyntax(_("\037channel\037 ENFORCE"));
428  this->SetSyntax(_("\037channel\037 CLEAR"));
429  }
430 
431  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
432  {
433  Anope::string chan = params[0];
434  Anope::string cmd = params[1];
435  Anope::string mask = params.size() > 2 ? params[2] : "";
436 
437  ChannelInfo *ci = ChannelInfo::Find(params[0]);
438  if (ci == NULL)
439  {
440  source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
441  return;
442  }
443 
444  if (mask.empty() && (cmd.equals_ci("ADD") || cmd.equals_ci("DEL")))
445  this->OnSyntaxError(source, cmd);
446  else if (!source.AccessFor(ci).HasPriv("AKICK") && !source.HasPriv("chanserv/access/modify"))
447  source.Reply(ACCESS_DENIED);
448  else if (!cmd.equals_ci("LIST") && !cmd.equals_ci("VIEW") && !cmd.equals_ci("ENFORCE") && Anope::ReadOnly)
449  source.Reply(_("Sorry, channel autokick list modification is temporarily disabled."));
450  else if (cmd.equals_ci("ADD"))
451  this->DoAdd(source, ci, params);
452  else if (cmd.equals_ci("DEL"))
453  this->DoDel(source, ci, params);
454  else if (cmd.equals_ci("LIST"))
455  this->DoList(source, ci, params);
456  else if (cmd.equals_ci("VIEW"))
457  this->DoView(source, ci, params);
458  else if (cmd.equals_ci("ENFORCE"))
459  this->DoEnforce(source, ci);
460  else if (cmd.equals_ci("CLEAR"))
461  this->DoClear(source, ci);
462  else
463  this->OnSyntaxError(source, "");
464 
465  return;
466  }
467 
468  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
469  {
470  BotInfo *bi = Config->GetClient("NickServ");
471  this->SendSyntax(source);
472  source.Reply(" ");
473  source.Reply(_("Maintains the \002AutoKick list\002 for a channel. If a user\n"
474  "on the AutoKick list attempts to join the channel,\n"
475  "%s will ban that user from the channel, then kick\n"
476  "the user.\n"
477  " \n"
478  "The \002AKICK ADD\002 command adds the given nick or usermask\n"
479  "to the AutoKick list. If a \037reason\037 is given with\n"
480  "the command, that reason will be used when the user is\n"
481  "kicked; if not, the default reason is \"User has been\n"
482  "banned from the channel\".\n"
483  "When akicking a \037registered nick\037 the %s account\n"
484  "will be added to the akick list instead of the mask.\n"
485  "All users within that nickgroup will then be akicked.\n"),
486  source.service->nick.c_str(), bi ? bi->nick.c_str() : "NickServ");
487  source.Reply(_(
488  " \n"
489  "The \002AKICK DEL\002 command removes the given nick or mask\n"
490  "from the AutoKick list. It does not, however, remove any\n"
491  "bans placed by an AutoKick; those must be removed\n"
492  "manually.\n"
493  " \n"
494  "The \002AKICK LIST\002 command displays the AutoKick list, or\n"
495  "optionally only those AutoKick entries which match the\n"
496  "given mask.\n"
497  " \n"
498  "The \002AKICK VIEW\002 command is a more verbose version of the\n"
499  "\002AKICK LIST\002 command.\n"
500  " \n"
501  "The \002AKICK ENFORCE\002 command causes %s to enforce the\n"
502  "current AKICK list by removing those users who match an\n"
503  "AKICK mask.\n"
504  " \n"
505  "The \002AKICK CLEAR\002 command clears all entries of the\n"
506  "akick list."), source.service->nick.c_str());
507  return true;
508  }
509 };
510 
511 class CSAKick : public Module
512 {
514 
515  public:
516  CSAKick(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
517  commandcsakick(this)
518  {
519  }
520 
522  {
523  if (!c->ci || c->MatchesList(u, "EXCEPT"))
524  return EVENT_CONTINUE;
525 
526  for (unsigned j = 0, end = c->ci->GetAkickCount(); j < end; ++j)
527  {
528  AutoKick *autokick = c->ci->GetAkick(j);
529  bool kick = false;
530 
531  if (autokick->nc)
532  kick = autokick->nc == u->Account();
533  else if (IRCD->IsChannelValid(autokick->mask))
534  {
535  Channel *chan = Channel::Find(autokick->mask);
536  kick = chan != NULL && chan->FindUser(u);
537  }
538  else
539  kick = Entry("BAN", autokick->mask).Matches(u);
540 
541  if (kick)
542  {
543  Log(LOG_DEBUG_2) << u->nick << " matched akick " << (autokick->nc ? autokick->nc->display : autokick->mask);
544  autokick->last_used = Anope::CurTime;
545  if (!autokick->nc && autokick->mask.find('#') == Anope::string::npos)
546  mask = autokick->mask;
547  reason = autokick->reason;
548  if (reason.empty())
549  reason = Language::Translate(u, Config->GetModule(this)->Get<const Anope::string>("autokickreason").c_str());
550  if (reason.empty())
551  reason = Language::Translate(u, _("User has been banned from the channel"));
552  return EVENT_STOP;
553  }
554  }
555 
556  return EVENT_CONTINUE;
557  }
558 };
559 
Serialize::Reference< NickCore > nc
Definition: account.h:47
Definition: bots.h:24
CoreExport bool ReadOnly
Definition: main.cpp:28
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: cs_akick.cpp:170
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: cs_akick.cpp:468
bool Matches(User *u, bool full=false) const
Definition: modes.cpp:830
void EraseAkick(unsigned index)
Definition: regchannel.cpp:567
Definition: hashcomp.h:84
unsigned GetAkickCount() const
Definition: regchannel.cpp:562
void clear()
Definition: anope.h:187
CommandCSAKick commandcsakick
Definition: cs_akick.cpp:513
Anope::string name
Definition: regchannel.h:63
#define CHAN_X_NOT_IN_USE
Definition: language.h:85
Anope::string nick
Definition: account.h:37
#define ACCESS_DENIED
Definition: language.h:73
Anope::string last_usermask
Definition: account.h:41
void Process(std::vector< Anope::string > &)
Definition: misc.cpp:144
Anope::string nick
Definition: modes.h:394
Definition: users.h:34
void AddEntry(const ListEntry &entry)
Definition: misc.cpp:134
EventReturn OnCheckKick(User *u, Channel *c, Anope::string &mask, Anope::string &reason) anope_override
Definition: cs_akick.cpp:521
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
CoreExport time_t CurTime
Definition: main.cpp:41
void DoView(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: cs_akick.cpp:371
bool HasPriv(const Anope::string &priv) const
Definition: access.cpp:384
virtual bool IsExtbanValid(const Anope::string &)
Definition: protocol.h:238
const Anope::string & GetNick() const
Definition: command.cpp:26
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
CoreExport Serialize::Checker< nickalias_map > NickAliasList
std::pair< ModeList::iterator, ModeList::iterator > GetModeList(const Anope::string &name)
Definition: channels.cpp:243
bool CheckKick(User *user)
Definition: channels.cpp:890
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
Anope::string host
Definition: modes.h:394
std::map< Anope::string, Anope::string > ListEntry
Definition: lists.h:68
size_type length() const
Definition: anope.h:131
NickCore * GetFounder() const
Definition: regchannel.cpp:364
Serialize::Reference< ChannelInfo > ci
Definition: regchannel.h:30
Definition: Config.cs:26
Channel * c
Definition: regchannel.h:79
CoreExport bool Match(const string &str, const string &mask, bool case_sensitive=false, bool use_regex=false)
Definition: misc.cpp:407
Anope::string real
Definition: modes.h:394
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
static const size_type npos
Definition: anope.h:44
bool IsEmpty() const
Definition: misc.cpp:139
void Reply(const char *message,...)
Definition: command.cpp:96
Anope::string reason
Definition: regchannel.h:35
time_t last_used
Definition: regchannel.h:38
Anope::string user
Definition: modes.h:394
string & trim(const Anope::string &what=" \t\r\n")
Definition: anope.h:177
void DoEnforce(CommandSource &source, ChannelInfo *ci)
Definition: cs_akick.cpp:384
CSAKick(const Anope::string &modname, const Anope::string &creator)
Definition: cs_akick.cpp:516
static Anope::map< std::pair< bool, Anope::string > > modes
Definition: cs_mode.cpp:745
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
void DoClear(CommandSource &source, ChannelInfo *ci)
Definition: cs_akick.cpp:410
#define UNKNOWN
Definition: language.h:88
CoreExport IRCDProto * IRCD
Definition: protocol.cpp:23
Anope::string creator
Definition: regchannel.h:36
EventReturn
Definition: modules.h:129
#define MODULE_INIT(x)
Definition: modules.h:45
#define CHAN_EXCEPTED
Definition: language.h:110
CoreExport const char * Translate(const char *string)
Definition: language.cpp:59
ChanUserList users
Definition: channels.h:56
ChanUserContainer * FindUser(User *u) const
Definition: channels.cpp:173
AutoKick * GetAkick(unsigned index) const
Definition: regchannel.cpp:552
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
AccessGroup AccessFor(const User *u)
Definition: regchannel.cpp:413
size_type find_first_not_of(const string &_str, size_type pos=0) const
Definition: anope.h:205
Anope::string stringify(const T &x)
Definition: anope.h:710
#define CHAN_X_NOT_REGISTERED
Definition: language.h:84
Anope::string nick
Definition: users.h:62
AccessGroup AccessFor(ChannelInfo *ci)
Definition: command.cpp:41
virtual bool IsChannelValid(const Anope::string &)
Definition: protocol.cpp:372
Anope::string mask
Definition: regchannel.h:32
Serialize::Reference< NickCore > nc
Definition: regchannel.h:33
static Channel * Find(const Anope::string &name)
Definition: channels.cpp:920
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: cs_akick.cpp:358
CoreExport user_map UserListByNick
Definition: users.cpp:28
void SendSyntax(CommandSource &)
Definition: command.cpp:145
NickCore * GetAccount()
Definition: command.cpp:36
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
AutoKick * AddAkick(const Anope::string &user, NickCore *akicknc, const Anope::string &reason, time_t t=Anope::CurTime, time_t lu=0)
Definition: regchannel.cpp:519
CoreExport Anope::string strftime(time_t t, const NickCore *nc=NULL, bool short_output=false)
Definition: misc.cpp:356
Definition: modes.h:388
void ProcessList(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params, ListFormatter &list)
Definition: cs_akick.cpp:255
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: cs_akick.cpp:431
size_type find(const string &_str, size_type pos=0) const
Definition: anope.h:192
CommandCSAKick(Module *creator)
Definition: cs_akick.cpp:420
time_t addtime
Definition: regchannel.h:37
#define _(x)
Definition: services.h:50
bool HasExt(const Anope::string &name) const
Definition: extensible.cpp:31
ListFormatter & AddColumn(const Anope::string &name)
Definition: misc.cpp:128
void ClearAkick()
Definition: regchannel.cpp:575
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: cs_akick.cpp:16
Module * owner
Definition: service.h:84