Anope IRC Services  Version 2.0
cs_xop.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 namespace
15 {
16  std::vector<Anope::string> order;
17  std::map<Anope::string, std::vector<Anope::string> > permissions;
18 }
19 
20 class XOPChanAccess : public ChanAccess
21 {
22  public:
24 
26  {
27  }
28 
29  bool HasPriv(const Anope::string &priv) const anope_override
30  {
31  for (std::vector<Anope::string>::iterator it = std::find(order.begin(), order.end(), this->type); it != order.end(); ++it)
32  {
33  const std::vector<Anope::string> &privs = permissions[*it];
34  if (std::find(privs.begin(), privs.end(), priv) != privs.end())
35  return true;
36  }
37  return false;
38  }
39 
41  {
42  return this->type;
43  }
44 
46  {
47  this->type = data;
48  }
49 
50  static Anope::string DetermineLevel(const ChanAccess *access)
51  {
52  if (access->provider->name == "access/xop")
53  {
54  const XOPChanAccess *xaccess = anope_dynamic_static_cast<const XOPChanAccess *>(access);
55  return xaccess->type;
56  }
57  else
58  {
59  std::map<Anope::string, int> count;
60 
61  for (std::map<Anope::string, std::vector<Anope::string> >::const_iterator it = permissions.begin(), it_end = permissions.end(); it != it_end; ++it)
62  {
63  int &c = count[it->first];
64  const std::vector<Anope::string> &perms = it->second;
65  for (unsigned i = 0; i < perms.size(); ++i)
66  if (access->HasPriv(perms[i]))
67  ++c;
68  }
69 
70  Anope::string max;
71  int maxn = 0;
72  for (std::map<Anope::string, int>::iterator it = count.begin(), it_end = count.end(); it != it_end; ++it)
73  if (it->second > maxn)
74  {
75  maxn = it->second;
76  max = it->first;
77  }
78 
79  return max;
80  }
81  }
82 };
83 
85 {
86  public:
87  XOPAccessProvider(Module *o) : AccessProvider(o, "access/xop")
88  {
89  }
90 
92  {
93  return new XOPChanAccess(this);
94  }
95 };
96 
97 class CommandCSXOP : public Command
98 {
99  private:
100  void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
101  {
102  Anope::string mask = params.size() > 2 ? params[2] : "";
103 
104  if (mask.empty())
105  {
106  this->OnSyntaxError(source, "ADD");
107  return;
108  }
109 
110  if (Anope::ReadOnly)
111  {
112  source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
113  return;
114  }
115 
116  XOPChanAccess tmp_access(NULL);
117  tmp_access.ci = ci;
118  tmp_access.type = source.command.upper();
119 
120  AccessGroup access = source.AccessFor(ci);
121  const ChanAccess *highest = access.Highest();
122  bool override = false;
123 
124  std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
125  access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
126 
127  if (!access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
128  {
129  if (source.HasPriv("chanserv/access/modify"))
130  override = true;
131  else
132  {
133  source.Reply(ACCESS_DENIED);
134  return;
135  }
136  }
137 
138  if (IRCD->IsChannelValid(mask))
139  {
140  if (Config->GetModule("chanserv")->Get<bool>("disallow_channel_access"))
141  {
142  source.Reply(_("Channels may not be on access lists."));
143  return;
144  }
145 
146  ChannelInfo *targ_ci = ChannelInfo::Find(mask);
147  if (targ_ci == NULL)
148  {
149  source.Reply(CHAN_X_NOT_REGISTERED, mask.c_str());
150  return;
151  }
152  else if (ci == targ_ci)
153  {
154  source.Reply(_("You can't add a channel to its own access list."));
155  return;
156  }
157 
158  mask = targ_ci->name;
159  }
160  else
161  {
162  const NickAlias *na = NickAlias::Find(mask);
163  if (!na && Config->GetModule("chanserv")->Get<bool>("disallow_hostmask_access"))
164  {
165  source.Reply(_("Masks and unregistered users may not be on access lists."));
166  return;
167  }
168  else if (mask.find_first_of("!*@") == Anope::string::npos && !na)
169  {
170  User *targ = User::Find(mask, true);
171  if (targ != NULL)
172  mask = "*!*@" + targ->GetDisplayedHost();
173  else
174  {
175  source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
176  return;
177  }
178  }
179  }
180 
181  for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
182  {
183  const ChanAccess *a = ci->GetAccess(i);
184 
185  if (a->Mask().equals_ci(mask))
186  {
187  if ((!highest || *a >= *highest) && !access.founder && !source.HasPriv("chanserv/access/modify"))
188  {
189  source.Reply(ACCESS_DENIED);
190  return;
191  }
192 
193  delete ci->EraseAccess(i);
194  break;
195  }
196  }
197 
198  unsigned access_max = Config->GetModule("chanserv")->Get<unsigned>("accessmax", "1024");
199  if (access_max && ci->GetDeepAccessCount() >= access_max)
200  {
201  source.Reply(_("Sorry, you can only have %d access entries on a channel, including access entries from other channels."), access_max);
202  return;
203  }
204 
205  ServiceReference<AccessProvider> provider("AccessProvider", "access/xop");
206  if (!provider)
207  return;
209  acc->SetMask(mask, ci);
210  acc->creator = source.GetNick();
211  acc->type = source.command.upper();
212  acc->last_seen = 0;
213  acc->created = Anope::CurTime;
214  ci->AddAccess(acc);
215 
216  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to add " << mask;
217 
218  FOREACH_MOD(OnAccessAdd, (ci, source, acc));
219  source.Reply(_("\002%s\002 added to %s %s list."), acc->Mask().c_str(), ci->name.c_str(), source.command.c_str());
220  }
221 
222  void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
223  {
224  NickCore *nc = source.nc;
225  Anope::string mask = params.size() > 2 ? params[2] : "";
226 
227  if (mask.empty())
228  {
229  this->OnSyntaxError(source, "DEL");
230  return;
231  }
232 
233  if (Anope::ReadOnly)
234  {
235  source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
236  return;
237  }
238 
239  if (!ci->GetAccessCount())
240  {
241  source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
242  return;
243  }
244 
245  XOPChanAccess tmp_access(NULL);
246  tmp_access.ci = ci;
247  tmp_access.type = source.command.upper();
248 
249  AccessGroup access = source.AccessFor(ci);
250  const ChanAccess *highest = access.Highest();
251  bool override = false;
252 
253  if (!isdigit(mask[0]) && mask.find_first_of("#!*@") == Anope::string::npos && !NickAlias::Find(mask))
254  {
255  User *targ = User::Find(mask, true);
256  if (targ != NULL)
257  mask = "*!*@" + targ->GetDisplayedHost();
258  else
259  {
260  source.Reply(NICK_X_NOT_REGISTERED, mask.c_str());
261  return;
262  }
263  }
264 
265  std::vector<Anope::string>::iterator cmd_it = std::find(order.begin(), order.end(), source.command.upper()),
266  access_it = highest ? std::find(order.begin(), order.end(), XOPChanAccess::DetermineLevel(highest)) : order.end();
267 
268  if (!mask.equals_ci(nc->display) && !access.founder && (!access.HasPriv("ACCESS_CHANGE") || cmd_it <= access_it))
269  {
270  if (source.HasPriv("chanserv/access/modify"))
271  override = true;
272  else
273  {
274  source.Reply(ACCESS_DENIED);
275  return;
276  }
277  }
278 
279  /* Special case: is it a number/list? Only do search if it isn't. */
280  if (isdigit(mask[0]) && mask.find_first_not_of("1234567890,-") == Anope::string::npos)
281  {
282  class XOPDelCallback : public NumberList
283  {
284  CommandSource &source;
285  ChannelInfo *ci;
286  Command *c;
287  unsigned deleted;
288  Anope::string nicks;
289  bool override;
290  public:
291  XOPDelCallback(CommandSource &_source, ChannelInfo *_ci, Command *_c, bool _override, const Anope::string &numlist) : NumberList(numlist, true), source(_source), ci(_ci), c(_c), deleted(0), override(_override)
292  {
293  }
294 
295  ~XOPDelCallback()
296  {
297  if (!deleted)
298  source.Reply(_("No matching entries on %s %s list."), ci->name.c_str(), source.command.c_str());
299  else
300  {
301  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, c, ci) << "to delete " << nicks;
302 
303  if (deleted == 1)
304  source.Reply(_("Deleted one entry from %s %s list."), ci->name.c_str(), source.command.c_str());
305  else
306  source.Reply(_("Deleted %d entries from %s %s list."), deleted, ci->name.c_str(), source.command.c_str());
307  }
308  }
309 
310  void HandleNumber(unsigned number) anope_override
311  {
312  if (!number || number > ci->GetAccessCount())
313  return;
314 
315  ChanAccess *caccess = ci->GetAccess(number - 1);
316 
317  if (caccess->provider->name != "access/xop" || this->source.command.upper() != caccess->AccessSerialize())
318  return;
319 
320  ++deleted;
321  if (!nicks.empty())
322  nicks += ", " + caccess->Mask();
323  else
324  nicks = caccess->Mask();
325 
326  ci->EraseAccess(number - 1);
327  FOREACH_MOD(OnAccessDel, (ci, source, caccess));
328  delete caccess;
329  }
330  }
331  delcallback(source, ci, this, override, mask);
332  delcallback.Process();
333  }
334  else
335  {
336  for (unsigned i = 0; i < ci->GetAccessCount(); ++i)
337  {
338  ChanAccess *a = ci->GetAccess(i);
339 
340  if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
341  continue;
342 
343  if (a->Mask().equals_ci(mask))
344  {
345  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to delete " << a->Mask();
346 
347  source.Reply(_("\002%s\002 deleted from %s %s list."), a->Mask().c_str(), ci->name.c_str(), source.command.c_str());
348 
349  ci->EraseAccess(i);
350  FOREACH_MOD(OnAccessDel, (ci, source, a));
351  delete a;
352 
353  return;
354  }
355  }
356 
357  source.Reply(_("\002%s\002 not found on %s %s list."), mask.c_str(), ci->name.c_str(), source.command.c_str());
358  }
359  }
360 
361  void DoList(CommandSource &source, ChannelInfo *ci, const std::vector<Anope::string> &params)
362  {
363 
364  const Anope::string &nick = params.size() > 2 ? params[2] : "";
365 
366  AccessGroup access = source.AccessFor(ci);
367 
368  if (!access.HasPriv("ACCESS_LIST") && !source.HasCommand("chanserv/access/list"))
369  {
370  source.Reply(ACCESS_DENIED);
371  return;
372  }
373 
374  if (!ci->GetAccessCount())
375  {
376  source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
377  return;
378  }
379 
380  ListFormatter list(source.GetAccount());
381  list.AddColumn(_("Number")).AddColumn(_("Mask"));
382 
383  if (!nick.empty() && nick.find_first_not_of("1234567890,-") == Anope::string::npos)
384  {
385  class XOPListCallback : public NumberList
386  {
387  ListFormatter &list;
388  ChannelInfo *ci;
389  CommandSource &source;
390  public:
391  XOPListCallback(ListFormatter &_list, ChannelInfo *_ci, const Anope::string &numlist, CommandSource &src) : NumberList(numlist, false), list(_list), ci(_ci), source(src)
392  {
393  }
394 
395  void HandleNumber(unsigned Number) anope_override
396  {
397  if (!Number || Number > ci->GetAccessCount())
398  return;
399 
400  const ChanAccess *a = ci->GetAccess(Number - 1);
401 
402  if (a->provider->name != "access/xop" || this->source.command.upper() != a->AccessSerialize())
403  return;
404 
406  entry["Number"] = stringify(Number);
407  entry["Mask"] = a->Mask();
408  this->list.AddEntry(entry);
409  }
410  } nl_list(list, ci, nick, source);
411  nl_list.Process();
412  }
413  else
414  {
415  for (unsigned i = 0, end = ci->GetAccessCount(); i < end; ++i)
416  {
417  const ChanAccess *a = ci->GetAccess(i);
418 
419  if (a->provider->name != "access/xop" || source.command.upper() != a->AccessSerialize())
420  continue;
421  else if (!nick.empty() && !Anope::Match(a->Mask(), nick))
422  continue;
423 
425  entry["Number"] = stringify(i + 1);
426  entry["Mask"] = a->Mask();
427  list.AddEntry(entry);
428  }
429  }
430 
431  if (list.IsEmpty())
432  source.Reply(_("No matching entries on %s access list."), ci->name.c_str());
433  else
434  {
435  std::vector<Anope::string> replies;
436  list.Process(replies);
437 
438  source.Reply(_("%s list for %s"), source.command.c_str(), ci->name.c_str());
439  for (unsigned i = 0; i < replies.size(); ++i)
440  source.Reply(replies[i]);
441  }
442  }
443 
445  {
446  if (Anope::ReadOnly)
447  {
448  source.Reply(_("Sorry, channel %s list modification is temporarily disabled."), source.command.c_str());
449  return;
450  }
451 
452  if (!ci->GetAccessCount())
453  {
454  source.Reply(_("%s %s list is empty."), ci->name.c_str(), source.command.c_str());
455  return;
456  }
457 
458  if (!source.AccessFor(ci).HasPriv("FOUNDER") && !source.HasPriv("chanserv/access/modify"))
459  {
460  source.Reply(ACCESS_DENIED);
461  return;
462  }
463 
464  bool override = !source.AccessFor(ci).HasPriv("FOUNDER");
465  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to clear the access list";
466 
467  for (unsigned i = ci->GetAccessCount(); i > 0; --i)
468  {
469  const ChanAccess *access = ci->GetAccess(i - 1);
470 
471  if (access->provider->name != "access/xop" || source.command.upper() != access->AccessSerialize())
472  continue;
473 
474  delete ci->EraseAccess(i - 1);
475  }
476 
477  FOREACH_MOD(OnAccessClear, (ci, source));
478 
479  source.Reply(_("Channel %s %s list has been cleared."), ci->name.c_str(), source.command.c_str());
480  }
481 
482  public:
483  CommandCSXOP(Module *modname) : Command(modname, "chanserv/xop", 2, 4)
484  {
485  this->SetSyntax(_("\037channel\037 ADD \037mask\037"));
486  this->SetSyntax(_("\037channel\037 DEL {\037mask\037 | \037entry-num\037 | \037list\037}"));
487  this->SetSyntax(_("\037channel\037 LIST [\037mask\037 | \037list\037]"));
488  this->SetSyntax(_("\037channel\037 CLEAR"));
489  }
490 
492  {
493  return Anope::printf(Language::Translate(source.GetAccount(), _("Modify the list of %s users")), source.command.upper().c_str());
494  }
495 
496  void Execute(CommandSource &source, const std::vector<Anope::string> &params)
497  {
498  ChannelInfo *ci = ChannelInfo::Find(params[0]);
499  if (ci == NULL)
500  {
501  source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
502  return;
503  }
504 
505  const Anope::string &cmd = params[1];
506 
507  if (cmd.equals_ci("ADD"))
508  return this->DoAdd(source, ci, params);
509  else if (cmd.equals_ci("DEL"))
510  return this->DoDel(source, ci, params);
511  else if (cmd.equals_ci("LIST"))
512  return this->DoList(source, ci, params);
513  else if (cmd.equals_ci("CLEAR"))
514  return this->DoClear(source, ci);
515  else
516  this->OnSyntaxError(source, "");
517  }
518 
519 
520  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
521  {
522  const Anope::string &cmd = source.command.upper();
523 
524  this->SendSyntax(source);
525  source.Reply(" ");
526  source.Reply(_("Maintains the \002%s list\002 for a channel. Users who match an access entry\n"
527  "on the %s list receive the following privileges:\n"
528  " "), cmd.c_str(), cmd.c_str());
529 
530  Anope::string buf;
531  for (unsigned i = 0; i < permissions[cmd].size(); ++i)
532  {
533  buf += ", " + permissions[cmd][i];
534  if (buf.length() > 75)
535  {
536  source.Reply(" %s\n", buf.substr(2).c_str());
537  buf.clear();
538  }
539  }
540  if (!buf.empty())
541  {
542  source.Reply(" %s\n", buf.substr(2).c_str());
543  buf.clear();
544  }
545 
546  source.Reply(_(" \n"
547  "The \002%s ADD\002 command adds the given nickname to the\n"
548  "%s list.\n"
549  " \n"
550  "The \002%s DEL\002 command removes the given nick from the\n"
551  "%s list. If a list of entry numbers is given, those\n"
552  "entries are deleted. (See the example for LIST below.)\n"
553  " \n"
554  "The \002%s LIST\002 command displays the %s list. If\n"
555  "a wildcard mask is given, only those entries matching the\n"
556  "mask are displayed. If a list of entry numbers is given,\n"
557  "only those entries are shown; for example:\n"
558  " \002%s #channel LIST 2-5,7-9\002\n"
559  " Lists %s entries numbered 2 through 5 and\n"
560  " 7 through 9.\n"
561  " \n"
562  "The \002%s CLEAR\002 command clears all entries of the\n"
563  "%s list."), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(),
564  cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str(), cmd.c_str());
565  source.Reply(_(" \n"
566  "The \002%s\002 commands are limited to founders\n"
567  "(unless SECUREOPS is off). However, any user on the\n"
568  "VOP list or above may use the \002%s LIST\002 command.\n"
569  " \n"), cmd.c_str(), cmd.c_str());
570  BotInfo *access_bi, *flags_bi;
571  Anope::string access_cmd, flags_cmd;
572  Command::FindCommandFromService("chanserv/access", access_bi, access_cmd);
573  Command::FindCommandFromService("chanserv/flags", flags_bi, access_cmd);
574  if (!access_cmd.empty() || !flags_cmd.empty())
575  {
576  source.Reply(_("Alternative methods of modifying channel access lists are\n"
577  "available. "));
578  if (!access_cmd.empty())
579  source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
580  "about the access list."), Config->StrictPrivmsg.c_str(), access_bi->nick.c_str(), access_cmd.c_str());
581  if (!flags_cmd.empty())
582  source.Reply(_("See \002%s%s HELP %s\002 for more information\n"
583  "about the flags system."), Config->StrictPrivmsg.c_str(), flags_bi->nick.c_str(), flags_cmd.c_str());
584  }
585  return true;
586  }
587 };
588 
589 class CSXOP : public Module
590 {
593 
594  public:
595  CSXOP(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
596  accessprovider(this), commandcsxop(this)
597  {
598  this->SetPermanent(true);
599 
600  }
601 
603  {
604  order.clear();
605  permissions.clear();
606 
607  for (int i = 0; i < conf->CountBlock("privilege"); ++i)
608  {
609  Configuration::Block *block = conf->GetBlock("privilege", i);
610  const Anope::string &pname = block->Get<const Anope::string>("name");
611 
613  if (p == NULL)
614  continue;
615 
616  const Anope::string &xop = block->Get<const Anope::string>("xop");
617  if (pname.empty() || xop.empty())
618  continue;
619 
620  permissions[xop].push_back(pname);
621  }
622 
623  for (int i = 0; i < conf->CountBlock("command"); ++i)
624  {
625  Configuration::Block *block = conf->GetBlock("command", i);
626  const Anope::string &cname = block->Get<const Anope::string>("name"),
627  &cserv = block->Get<const Anope::string>("command");
628  if (cname.empty() || cserv != "chanserv/xop")
629  continue;
630 
631  order.push_back(cname);
632  }
633  }
634 };
635 
Definition: bots.h:24
CoreExport bool ReadOnly
Definition: main.cpp:28
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: cs_xop.cpp:520
static NickAlias * Find(const Anope::string &nick)
Definition: nickalias.cpp:121
CommandCSXOP commandcsxop
Definition: cs_xop.cpp:592
Anope::string AccessSerialize() const
Definition: cs_xop.cpp:40
Definition: hashcomp.h:84
void clear()
Definition: anope.h:187
Anope::string name
Definition: regchannel.h:63
CSXOP(const Anope::string &modname, const Anope::string &creator)
Definition: cs_xop.cpp:595
void DoClear(CommandSource &source, ChannelInfo *ci)
Definition: cs_xop.cpp:444
void push_back(char c)
Definition: anope.h:142
#define ACCESS_DENIED
Definition: language.h:73
CoreExport string printf(const char *fmt,...)
Definition: misc.cpp:536
static bool FindCommandFromService(const Anope::string &command_service, BotInfo *&bi, Anope::string &name)
Definition: command.cpp:287
Definition: users.h:34
bool HasCommand(const Anope::string &cmd)
Definition: command.cpp:60
void AddEntry(const ListEntry &entry)
Definition: misc.cpp:134
#define NICK_X_NOT_REGISTERED
Definition: language.h:79
Anope::string creator
Definition: access.h:93
virtual Anope::string AccessSerialize() const =0
string upper() const
Definition: anope.h:266
XOPChanAccess(AccessProvider *p)
Definition: cs_xop.cpp:25
unsigned GetDeepAccessCount() const
Definition: regchannel.cpp:479
time_t created
Definition: access.h:95
bool founder
Definition: access.h:150
Anope::string type
Definition: cs_xop.cpp:23
bool equals_ci(const char *_str) const
Definition: anope.h:78
size_type find_first_of(const string &_str, size_type pos=0) const
Definition: anope.h:202
void DoList(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: cs_xop.cpp:361
CoreExport time_t CurTime
Definition: main.cpp:41
bool HasPriv(const Anope::string &priv) const
Definition: access.cpp:384
const Anope::string & GetNick() const
Definition: command.cpp:26
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
static Privilege * FindPrivilege(const Anope::string &name)
Definition: access.cpp:105
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
CommandCSXOP(Module *modname)
Definition: cs_xop.cpp:483
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
std::map< Anope::string, Anope::string > ListEntry
Definition: lists.h:68
size_type length() const
Definition: anope.h:131
ChanAccess * Create() anope_override
Definition: cs_xop.cpp:91
Block * GetBlock(const Anope::string &name, int num=0)
Definition: config.cpp:43
Definition: Config.cs:26
virtual bool HasPriv(const Anope::string &name) const =0
time_t last_seen
Definition: access.h:94
void Execute(CommandSource &source, const std::vector< Anope::string > &params)
Definition: cs_xop.cpp:496
const Anope::string GetDesc(CommandSource &source) const anope_override
Definition: cs_xop.cpp:491
CoreExport bool Match(const string &str, const string &mask, bool case_sensitive=false, bool use_regex=false)
Definition: misc.cpp:407
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
bool HasPriv(const Anope::string &priv) const anope_override
Definition: cs_xop.cpp:29
ChanAccess * EraseAccess(unsigned index)
Definition: regchannel.cpp:503
static const size_type npos
Definition: anope.h:44
Anope::string command
Definition: commands.h:69
void Reply(const char *message,...)
Definition: command.cpp:96
const Anope::string & GetDisplayedHost() const
Definition: users.cpp:203
const Anope::string & Mask() const
Definition: access.cpp:196
bool HasPriv(const Anope::string &cmd)
Definition: command.cpp:69
XOPAccessProvider accessprovider
Definition: cs_xop.cpp:591
Anope::string display
Definition: account.h:113
const ChanAccess * Highest() const
Definition: access.cpp:416
XOPAccessProvider(Module *o)
Definition: cs_xop.cpp:87
Serialize::Reference< ChannelInfo > ci
Definition: access.h:92
virtual ChanAccess * Create()=0
unsigned GetAccessCount() const
Definition: regchannel.cpp:474
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
void AddAccess(ChanAccess *access)
Definition: regchannel.cpp:398
CoreExport IRCDProto * IRCD
Definition: protocol.cpp:23
AccessProvider * provider
Definition: access.h:90
void AccessUnserialize(const Anope::string &data) anope_override
Definition: cs_xop.cpp:45
#define MODULE_INIT(x)
Definition: modules.h:45
CoreExport const char * Translate(const char *string)
Definition: language.cpp:59
void SetSyntax(const Anope::string &s)
Definition: command.cpp:140
size_type find_first_not_of(const string &_str, size_type pos=0) const
Definition: anope.h:205
void DoAdd(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: cs_xop.cpp:100
Anope::string stringify(const T &x)
Definition: anope.h:710
Anope::string name
Definition: service.h:88
#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
static User * Find(const Anope::string &name, bool nick_only=false)
Definition: users.cpp:815
void DoDel(CommandSource &source, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: cs_xop.cpp:222
T anope_dynamic_static_cast(O ptr)
Definition: anope.h:774
static Anope::string DetermineLevel(const ChanAccess *access)
Definition: cs_xop.cpp:50
Reference< NickCore > nc
Definition: commands.h:61
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
T Get(const Anope::string &tag)
Definition: config.h:44
void SetMask(const Anope::string &mask, ChannelInfo *ci)
Definition: access.cpp:165
void SetPermanent(bool state)
Definition: module.cpp:84
void OnReload(Configuration::Conf *conf) anope_override
Definition: cs_xop.cpp:602
iterator begin()
Definition: anope.h:282
#define _(x)
Definition: services.h:50
ListFormatter & AddColumn(const Anope::string &name)
Definition: misc.cpp:128
ChanAccess * GetAccess(unsigned index) const
Definition: regchannel.cpp:403