Anope IRC Services  Version 2.0
fantasy.cpp
Go to the documentation of this file.
1 /* Fantasy functionality
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 
15 {
16  public:
17  CommandBSSetFantasy(Module *creator, const Anope::string &sname = "botserv/set/fantasy") : Command(creator, sname, 2, 2)
18  {
19  this->SetDesc(_("Enable fantaisist commands"));
20  this->SetSyntax(_("\037channel\037 {\037ON|OFF\037}"));
21  }
22 
23  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
24  {
25  ChannelInfo *ci = ChannelInfo::Find(params[0]);
26  const Anope::string &value = params[1];
27 
28  if (ci == NULL)
29  {
30  source.Reply(CHAN_X_NOT_REGISTERED, params[0].c_str());
31  return;
32  }
33 
34  if (!source.HasPriv("botserv/administration") && !source.AccessFor(ci).HasPriv("SET"))
35  {
36  source.Reply(ACCESS_DENIED);
37  return;
38  }
39 
40  if (Anope::ReadOnly)
41  {
42  source.Reply(_("Sorry, bot option setting is temporarily disabled."));
43  return;
44  }
45 
46  if (value.equals_ci("ON"))
47  {
48  bool override = !source.AccessFor(ci).HasPriv("SET");
49  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to enable fantasy";
50 
51  ci->Extend<bool>("BS_FANTASY");
52  source.Reply(_("Fantasy mode is now \002on\002 on channel %s."), ci->name.c_str());
53  }
54  else if (value.equals_ci("OFF"))
55  {
56  bool override = !source.AccessFor(ci).HasPriv("SET");
57  Log(override ? LOG_OVERRIDE : LOG_COMMAND, source, this, ci) << "to disable fantasy";
58 
59  ci->Shrink<bool>("BS_FANTASY");
60  source.Reply(_("Fantasy mode is now \002off\002 on channel %s."), ci->name.c_str());
61  }
62  else
63  this->OnSyntaxError(source, source.command);
64  }
65 
67  {
68  this->SendSyntax(source);
69  source.Reply(_(" \n"
70  "Enables or disables \002fantasy\002 mode on a channel.\n"
71  "When it is enabled, users will be able to use\n"
72  "fantasy commands on a channel when prefixed\n"
73  "with one of the following fantasy characters: \002%s\002\n"
74  " \n"
75  "Note that users wanting to use fantaisist\n"
76  "commands MUST have enough access for both\n"
77  "the FANTASIA and the command they are executing."),
78  Config->GetModule(this->owner)->Get<const Anope::string>("fantasycharacter", "!").c_str());
79  return true;
80  }
81 };
82 
83 class Fantasy : public Module
84 {
86 
88 
89  public:
90  Fantasy(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
91  fantasy(this, "BS_FANTASY"), commandbssetfantasy(this)
92  {
93  }
94 
96  {
97  if (!u || !c || !c->ci || !c->ci->bi || msg.empty() || msg[0] == '\1')
98  return;
99 
100  if (Config->GetClient("BotServ") && !fantasy.HasExt(c->ci))
101  return;
102 
103  std::vector<Anope::string> params;
104  spacesepstream(msg).GetTokens(params);
105 
106  if (!msg.find(c->ci->bi->nick))
107  params.erase(params.begin());
108  else if (!msg.find_first_of(Config->GetModule(this)->Get<const Anope::string>("fantasycharacter", "!")))
109  params[0].erase(params[0].begin());
110  else
111  return;
112 
113  if (params.empty())
114  return;
115 
116  CommandInfo::map::const_iterator it = Config->Fantasy.end();
117  unsigned count = 0;
118  for (unsigned max = params.size(); it == Config->Fantasy.end() && max > 0; --max)
119  {
120  Anope::string full_command;
121  for (unsigned i = 0; i < max; ++i)
122  full_command += " " + params[i];
123  full_command.erase(full_command.begin());
124 
125  ++count;
126  it = Config->Fantasy.find(full_command);
127  }
128 
129  if (it == Config->Fantasy.end())
130  return;
131 
132  const CommandInfo &info = it->second;
133  ServiceReference<Command> cmd("Command", info.name);
134  if (!cmd)
135  {
136  Log(LOG_DEBUG) << "Fantasy command " << it->first << " exists for nonexistant service " << info.name << "!";
137  return;
138  }
139 
140  for (unsigned i = 0, j = params.size() - (count - 1); i < j; ++i)
141  params.erase(params.begin());
142 
143  /* Some commands take the channel as a first parameter */
144  if (info.prepend_channel)
145  params.insert(params.begin(), c->name);
146 
147  while (cmd->max_params > 0 && params.size() > cmd->max_params)
148  {
149  params[cmd->max_params - 1] += " " + params[cmd->max_params];
150  params.erase(params.begin() + cmd->max_params);
151  }
152 
153  // Command requires registered users only
154  if (!cmd->AllowUnregistered() && !u->Account())
155  return;
156 
157  if (params.size() < cmd->min_params)
158  return;
159 
160  CommandSource source(u->nick, u, u->Account(), u, c->ci->bi);
161  source.c = c;
162  source.command = it->first;
163  source.permission = info.permission;
164 
165  AccessGroup ag = c->ci->AccessFor(u);
166  bool has_fantasia = ag.HasPriv("FANTASIA") || source.HasPriv("chanserv/administration");
167 
168  EventReturn MOD_RESULT;
169  if (has_fantasia)
170  {
171  FOREACH_RESULT(OnBotFantasy, MOD_RESULT, (source, cmd, c->ci, params));
172  }
173  else
174  {
175  FOREACH_RESULT(OnBotNoFantasyAccess, MOD_RESULT, (source, cmd, c->ci, params));
176  }
177 
178  if (MOD_RESULT == EVENT_STOP || !has_fantasia)
179  return;
180 
181  if (MOD_RESULT != EVENT_ALLOW && !info.permission.empty() && !source.HasCommand(info.permission))
182  return;
183 
184  FOREACH_RESULT(OnPreCommand, MOD_RESULT, (source, cmd, params));
185  if (MOD_RESULT == EVENT_STOP)
186  return;
187 
188  Reference<NickCore> nc_reference(u->Account());
189  cmd->Execute(source, params);
190  if (!nc_reference)
191  source.nc = NULL;
192  FOREACH_MOD(OnPostCommand, (source, cmd, params));
193  }
194 
196  {
197  if (fantasy.HasExt(ci))
198  info.AddOption(_("Fantasy"));
199  }
200 };
201 
203 
Definition: bots.h:24
CoreExport bool ReadOnly
Definition: main.cpp:28
Anope::string permission
Definition: commands.h:34
virtual EventReturn OnPreCommand(CommandSource &source, Command *command, std::vector< Anope::string > &params)
Definition: modules.h:369
void AddOption(const Anope::string &opt)
Definition: misc.cpp:246
void OnBotInfo(CommandSource &source, BotInfo *bi, ChannelInfo *ci, InfoFormatter &info)
Definition: fantasy.cpp:195
SerializableExtensibleItem< bool > fantasy
Definition: fantasy.cpp:85
Anope::string name
Definition: commands.h:32
const ChannelInfo * ci
Definition: access.h:144
Definition: hashcomp.h:84
Anope::string name
Definition: regchannel.h:63
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: fantasy.cpp:23
#define ACCESS_DENIED
Definition: language.h:73
void AllowUnregistered(bool b)
Definition: command.cpp:164
virtual void Execute(CommandSource &source, const std::vector< Anope::string > &params)=0
Reference< Channel > c
Definition: commands.h:65
void GetTokens(T &token)
Definition: anope.h:587
size_t max_params
Definition: commands.h:103
Definition: users.h:34
T * Extend(const Anope::string &name, const T &what)
Definition: extensible.h:224
virtual void OnPostCommand(CommandSource &source, Command *command, const std::vector< Anope::string > &params)
Definition: modules.h:376
Fantasy(const Anope::string &modname, const Anope::string &creator)
Definition: fantasy.cpp:90
void OnPrivmsg(User *u, Channel *c, Anope::string &msg) anope_override
Definition: fantasy.cpp:95
#define FOREACH_RESULT(ename, ret, args)
Definition: modules.h:95
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
CommandBSSetFantasy commandbssetfantasy
Definition: fantasy.cpp:87
size_t min_params
Definition: commands.h:105
bool HasPriv(const Anope::string &priv) const
Definition: access.cpp:384
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
iterator erase(const iterator &i)
Definition: anope.h:155
static ChannelInfo * Find(const Anope::string &name)
Definition: regchannel.cpp:630
virtual EventReturn OnBotFantasy(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: modules.h:400
Definition: Config.cs:26
void Shrink(const Anope::string &name)
Definition: extensible.h:253
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:191
void Reply(const char *message,...)
Definition: command.cpp:96
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
virtual EventReturn OnBotNoFantasyAccess(CommandSource &source, Command *c, ChannelInfo *ci, const std::vector< Anope::string > &params)
Definition: modules.h:409
EventReturn
Definition: modules.h:129
#define MODULE_INIT(x)
Definition: modules.h:45
bool OnHelp(CommandSource &source, const Anope::string &) anope_override
Definition: fantasy.cpp:66
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
bool prepend_channel
Definition: commands.h:40
void SendSyntax(CommandSource &)
Definition: command.cpp:145
CommandBSSetFantasy(Module *creator, const Anope::string &sname="botserv/set/fantasy")
Definition: fantasy.cpp:17
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
bool HasExt(const Extensible *obj) const
Definition: extensible.h:111
iterator begin()
Definition: anope.h:282
#define _(x)
Definition: services.h:50