Anope IRC Services  Version 2.0
help.cpp
Go to the documentation of this file.
1 /* 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 CommandHelp : public Command
15 {
16  static const unsigned help_wrap_len = 40;
17 
19  {
20  for (unsigned i = 0; i < Config->CommandGroups.size(); ++i)
21  {
22  CommandGroup &gr = Config->CommandGroups[i];
23  if (gr.name == name)
24  return &gr;
25  }
26 
27  return NULL;
28  }
29 
30  public:
31  CommandHelp(Module *creator) : Command(creator, "generic/help", 0)
32  {
33  this->SetDesc(_("Displays this list and give information about commands"));
34  this->AllowUnregistered(true);
35  }
36 
37  void Execute(CommandSource &source, const std::vector<Anope::string> &params) anope_override
38  {
39  EventReturn MOD_RESULT;
40  FOREACH_RESULT(OnPreHelp, MOD_RESULT, (source, params));
41  if (MOD_RESULT == EVENT_STOP)
42  return;
43 
44  Anope::string source_command = source.command;
45  const BotInfo *bi = source.service;
46  const CommandInfo::map &map = source.c ? Config->Fantasy : bi->commands;
47  bool hide_privileged_commands = Config->GetBlock("options")->Get<bool>("hideprivilegedcommands"),
48  hide_registered_commands = Config->GetBlock("options")->Get<bool>("hideregisteredcommands");
49 
50  if (params.empty() || params[0].equals_ci("ALL"))
51  {
52  bool all = !params.empty() && params[0].equals_ci("ALL");
53  typedef std::map<CommandGroup *, std::list<Anope::string> > GroupInfo;
54  GroupInfo groups;
55 
56  if (all)
57  source.Reply(_("All available commands for \002%s\002:"), source.service->nick.c_str());
58 
59  for (CommandInfo::map::const_iterator it = map.begin(), it_end = map.end(); it != it_end; ++it)
60  {
61  const Anope::string &c_name = it->first;
62  const CommandInfo &info = it->second;
63 
64  if (info.hide)
65  continue;
66 
67  // Smaller command exists
68  Anope::string cmd;
69  spacesepstream(c_name).GetToken(cmd, 0);
70  if (cmd != it->first && map.count(cmd))
71  continue;
72 
73  ServiceReference<Command> c("Command", info.name);
74  if (!c)
75  continue;
76 
77  if (hide_registered_commands && !c->AllowUnregistered() && !source.GetAccount())
78  continue;
79 
80  if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
81  continue;
82 
83  if (!info.group.empty() && !all)
84  {
85  CommandGroup *gr = FindGroup(info.group);
86  if (gr != NULL)
87  {
88  groups[gr].push_back(c_name);
89  continue;
90  }
91  }
92 
93  source.command = c_name;
94  c->OnServHelp(source);
95 
96  }
97 
98  for (GroupInfo::iterator it = groups.begin(), it_end = groups.end(); it != it_end; ++it)
99  {
100  CommandGroup *gr = it->first;
101 
102  source.Reply(" ");
103  source.Reply("%s", gr->description.c_str());
104 
105  Anope::string buf;
106  for (std::list<Anope::string>::iterator it2 = it->second.begin(), it2_end = it->second.end(); it2 != it2_end; ++it2)
107  {
108  const Anope::string &c_name = *it2;
109 
110  buf += ", " + c_name;
111 
112  if (buf.length() > help_wrap_len)
113  {
114  source.Reply(" %s", buf.substr(2).c_str());
115  buf.clear();
116  }
117  }
118  if (buf.length() > 2)
119  {
120  source.Reply(" %s", buf.substr(2).c_str());
121  buf.clear();
122  }
123  }
124  if (!groups.empty())
125  {
126  source.Reply(" ");
127  source.Reply(_("Use the \002%s ALL\002 command to list all commands and their descriptions."), source_command.c_str());
128  }
129  }
130  else
131  {
132  bool helped = false;
133  for (unsigned max = params.size(); max > 0; --max)
134  {
135  Anope::string full_command;
136  for (unsigned i = 0; i < max; ++i)
137  full_command += " " + params[i];
138  full_command.erase(full_command.begin());
139 
140  CommandInfo::map::const_iterator it = map.find(full_command);
141  if (it == map.end())
142  continue;
143 
144  const CommandInfo &info = it->second;
145 
146  ServiceReference<Command> c("Command", info.name);
147  if (!c)
148  continue;
149 
150  if (hide_privileged_commands && !info.permission.empty() && !source.HasCommand(info.permission))
151  continue;
152 
153  // Allow unregistered users to see help for commands that they explicitly request help for
154 
155  const Anope::string &subcommand = params.size() > max ? params[max] : "";
156  source.command = full_command;
157  if (!c->OnHelp(source, subcommand))
158  continue;
159 
160  helped = true;
161 
162  /* Inform the user what permission is required to use the command */
163  if (!info.permission.empty())
164  {
165  source.Reply(" ");
166  source.Reply(_("Access to this command requires the permission \002%s\002 to be present in your opertype."), info.permission.c_str());
167  }
168  if (!c->AllowUnregistered() && !source.nc)
169  {
170  if (info.permission.empty())
171  source.Reply(" ");
172  source.Reply( _("You need to be identified to use this command."));
173  }
174  /* User doesn't have the proper permission to use this command */
175  else if (!info.permission.empty() && !source.HasCommand(info.permission))
176  {
177  source.Reply(_("You cannot use this command."));
178  }
179 
180  break;
181  }
182 
183  if (helped == false)
184  source.Reply(_("No help available for \002%s\002."), params[0].c_str());
185  }
186 
187  FOREACH_MOD(OnPostHelp, (source, params));
188 
189  return;
190  }
191 };
192 
193 class Help : public Module
194 {
196 
197  public:
198  Help(const Anope::string &modname, const Anope::string &creator) : Module(modname, creator, VENDOR),
199  commandhelp(this)
200  {
201 
202  }
203 };
204 
Definition: bots.h:24
Anope::string permission
Definition: commands.h:34
Help(const Anope::string &modname, const Anope::string &creator)
Definition: help.cpp:198
Anope::string name
Definition: commands.h:32
void clear()
Definition: anope.h:187
CommandHelp(Module *creator)
Definition: help.cpp:31
Anope::string group
Definition: commands.h:36
void AllowUnregistered(bool b)
Definition: command.cpp:164
CommandInfo::map commands
Definition: bots.h:33
Anope::string name
Definition: commands.h:21
static CommandGroup * FindGroup(const Anope::string &name)
Definition: help.cpp:18
#define FOREACH_RESULT(ename, ret, args)
Definition: modules.h:95
void SetDesc(const Anope::string &d)
Definition: command.cpp:130
virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand)
Definition: command.cpp:189
#define FOREACH_MOD(ename, args)
Definition: modules.h:62
iterator erase(const iterator &i)
Definition: anope.h:155
string substr(size_type pos=0, size_type n=npos) const
Definition: anope.h:277
static const unsigned help_wrap_len
Definition: help.cpp:16
size_type length() const
Definition: anope.h:131
void Execute(CommandSource &source, const std::vector< Anope::string > &params) anope_override
Definition: help.cpp:37
Definition: Config.cs:26
Definition: help.cpp:193
Anope::string description
Definition: commands.h:21
#define anope_override
Definition: services.h:56
bool empty() const
Definition: anope.h:126
EventReturn
Definition: modules.h:129
#define MODULE_INIT(x)
Definition: modules.h:45
bool AllowUnregistered() const
Definition: command.cpp:159
virtual void OnServHelp(CommandSource &source)
Definition: command.cpp:184
Anope::string name
Definition: service.h:88
bool hide
Definition: commands.h:38
bool GetToken(Anope::string &token)
Definition: hashcomp.cpp:99
const char * c_str() const
Definition: anope.h:117
iterator begin()
Definition: anope.h:282
#define _(x)
Definition: services.h:50
CommandHelp commandhelp
Definition: help.cpp:195