Anope IRC Services  Version 2.0
m_rewrite.cpp
Go to the documentation of this file.
1 /*
2  * (C) 2003-2014 Anope Team
3  * Contact us at team@anope.org
4  *
5  * Please read COPYING and README for further details.
6  */
7 
8 #include "module.h"
9 
10 struct Rewrite
11 {
13 
14  bool Matches(const std::vector<Anope::string> &message)
15  {
16  std::vector<Anope::string> sm;
17  spacesepstream(this->source_message).GetTokens(sm);
18 
19  for (unsigned i = 0; i < sm.size(); ++i)
20  if (i >= message.size() || (sm[i] != "$" && !sm[i].equals_ci(message[i])))
21  return false;
22 
23  return true;
24  }
25 
26  Anope::string Process(CommandSource &source, const std::vector<Anope::string> &params)
27  {
28  spacesepstream sep(this->target_message);
29  Anope::string token, message;
30 
31  while (sep.GetToken(token))
32  {
33  if (token[0] != '$')
34  message += " " + token;
35  else if (token == "$me")
36  message += " " + source.GetNick();
37  else
38  {
39  int num = -1, end = -1;
40  try
41  {
42  Anope::string num_str = token.substr(1);
43  size_t hy = num_str.find('-');
44  if (hy == Anope::string::npos)
45  {
46  num = convertTo<int>(num_str);
47  end = num + 1;
48  }
49  else
50  {
51  num = convertTo<int>(num_str.substr(0, hy));
52  if (hy == num_str.length() - 1)
53  end = params.size();
54  else
55  end = convertTo<int>(num_str.substr(hy + 1)) + 1;
56  }
57  }
58  catch (const ConvertException &)
59  {
60  continue;
61  }
62 
63  for (int i = num; i < end && static_cast<unsigned>(i) < params.size(); ++i)
64  message += " " + params[i];
65  }
66  }
67 
68  message.trim();
69  return message;
70  }
71 
72  static std::vector<Rewrite> rewrites;
73 
74  static Rewrite *Find(const Anope::string &client, const Anope::string &cmd)
75  {
76  for (unsigned i = 0; i < rewrites.size(); ++i)
77  {
78  Rewrite &r = rewrites[i];
79 
80  if ((client.empty() || r.client.equals_ci(client)) && (r.source_message.equals_ci(cmd) || r.source_message.find_ci(cmd + " ") == 0))
81  return &r;
82  }
83 
84  return NULL;
85  }
86 
87  static Rewrite *Match(const Anope::string &client, const std::vector<Anope::string> &params)
88  {
89  for (unsigned i = 0; i < rewrites.size(); ++i)
90  {
91  Rewrite &r = rewrites[i];
92 
93  if ((client.empty() || r.client.equals_ci(client)) && r.Matches(params))
94  return &r;
95  }
96 
97  return NULL;
98  }
99 };
100 
101 std::vector<Rewrite> Rewrite::rewrites;
102 
103 class RewriteCommand : public Command
104 {
105  public:
106  RewriteCommand(Module *creator) : Command(creator, "rewrite", 0, 0) { }
107 
108  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
109  {
110  std::vector<Anope::string> full_params = params;
111  full_params.insert(full_params.begin(), source.command);
112 
113  Rewrite *r = Rewrite::Match(!source.c ? source.service->nick : "", full_params);
114  if (r != NULL)
115  {
116  Anope::string new_message = r->Process(source, full_params);
117  Log(LOG_DEBUG) << "m_rewrite: Rewrote '" << source.command << (!params.empty() ? " " + params[0] : "") << "' to '" << new_message << "' using '" << r->source_message << "'";
118  source.service = BotInfo::Find(r->client, true);
119  if (!source.service)
120  return;
121  Command::Run(source, new_message);
122  }
123  else
124  Log() << "m_rewrite: Unable to rewrite '" << source.command << (!params.empty() ? " " + params[0] : "") << "'";
125  }
126 
128  {
129  Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command);
130  if (r != NULL && !r->desc.empty())
131  {
132  this->SetDesc(r->desc);
133  Command::OnServHelp(source);
134  }
135  }
136 
137  bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
138  {
139  Rewrite *r = Rewrite::Find(!source.c ? source.service->nick : "", source.command);
140  if (r != NULL && !r->desc.empty())
141  {
142  source.Reply(r->desc);
143  size_t sz = r->target_message.find(' ');
144  source.Reply(_("This command is an alias to the command %s."), sz != Anope::string::npos ? r->target_message.substr(0, sz).c_str() : r->target_message.c_str());
145  return true;
146  }
147  return false;
148  }
149 };
150 
151 class ModuleRewrite : public Module
152 {
154 
155  public:
156  ModuleRewrite(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR | EXTRA), cmdrewrite(this)
157  {
158  }
159 
161  {
162  Rewrite::rewrites.clear();
163 
164  for (int i = 0; i < conf->CountBlock("command"); ++i)
165  {
166  Configuration::Block *block = conf->GetBlock("command", i);
167 
168  if (!block->Get<bool>("rewrite"))
169  continue;
170 
171  Rewrite rw;
172 
173  rw.client = block->Get<const Anope::string>("service");
174  rw.source_message = block->Get<const Anope::string>("rewrite_source");
175  rw.target_message = block->Get<const Anope::string>("rewrite_target");
176  rw.desc = block->Get<const Anope::string>("rewrite_description");
177 
178  if (rw.client.empty() || rw.source_message.empty() || rw.target_message.empty())
179  continue;
180 
181  Rewrite::rewrites.push_back(rw);
182  }
183  }
184 };
185 
Anope::string desc
Definition: m_rewrite.cpp:12
bool Matches(const std::vector< Anope::string > &message)
Definition: m_rewrite.cpp:14
void GetTokens(T &token)
Definition: anope.h:587
void OnReload(Configuration::Conf *conf) anope_override
Definition: m_rewrite.cpp:160
Anope::string target_message
Definition: m_rewrite.cpp:12
static Rewrite * Find(const Anope::string &client, const Anope::string &cmd)
Definition: m_rewrite.cpp:74
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
bool equals_ci(const char *_str) const
Definition: anope.h:78
const Anope::string & GetNick() const
Definition: command.cpp:26
size_type find_ci(const string &_str, size_type pos=0) const
Definition: anope.h:194
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: m_rewrite.cpp:108
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
RewriteCommand cmdrewrite
Definition: m_rewrite.cpp:153
static Rewrite * Match(const Anope::string &client, const std::vector< Anope::string > &params)
Definition: m_rewrite.cpp:87
size_type length() const
Definition: anope.h:131
Block * GetBlock(const Anope::string &name, int num=0)
Definition: config.cpp:43
static const size_type npos
Definition: anope.h:44
void OnServHelp(CommandSource &source) anope_override
Definition: m_rewrite.cpp:127
string & trim(const Anope::string &what=" \t\r\n")
Definition: anope.h:177
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
static void Run(CommandSource &source, const Anope::string &message)
Definition: command.cpp:199
#define MODULE_INIT(x)
Definition: modules.h:45
RewriteCommand(Module *creator)
Definition: m_rewrite.cpp:106
Anope::string Process(CommandSource &source, const std::vector< Anope::string > &params)
Definition: m_rewrite.cpp:26
virtual void OnServHelp(CommandSource &source)
Definition: command.cpp:184
Anope::string client
Definition: m_rewrite.cpp:12
bool OnHelp(CommandSource &source, const Anope::string &subcommand) anope_override
Definition: m_rewrite.cpp:137
bool GetToken(Anope::string &token)
Definition: hashcomp.cpp:99
Anope::string source_message
Definition: m_rewrite.cpp:12
const char * c_str() const
Definition: anope.h:117
Definition: logger.h:53
T Get(const Anope::string &tag)
Definition: config.h:44
ModuleRewrite(const Anope::string &modname, const Anope::string &creator)
Definition: m_rewrite.cpp:156
static std::vector< Rewrite > rewrites
Definition: m_rewrite.cpp:72
size_type find(const string &_str, size_type pos=0) const
Definition: anope.h:192
#define _(x)
Definition: services.h:50
static BotInfo * Find(const Anope::string &nick, bool nick_only=false)
Definition: bots.cpp:249
Definition: modules.h:163