1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
|
/* Declarations for command data.
*
* (C) 2003-2024 Anope Team
* Contact us at team@anope.org
*
* Please read COPYING and README for further details.
*
* Based on the original code of Epona by Lara.
* Based on the original code of Services by Andy Church.
*/
#pragma once
#include "service.h"
#include "anope.h"
#include "channels.h"
struct CommandGroup final
{
Anope::string name, description;
};
/* Used in BotInfo::commands */
struct CommandInfo final
{
typedef Anope::map<CommandInfo> map;
/* Service name of the command */
Anope::string name;
/* Permission required to execute the command */
Anope::string permission;
/* Group this command is in */
Anope::string group;
/* whether or not to hide this command in help output */
bool hide = false;
/* Only used with fantasy */
bool prepend_channel = false;
};
/* Where the replies from commands go to. User inherits from this and is the normal
* source of a CommandReply
*/
struct CoreExport CommandReply
{
virtual ~CommandReply() = default;
virtual void SendMessage(BotInfo *source, const Anope::string &msg) = 0;
virtual void SendMessage(CommandSource &source, const Anope::string &msg);
};
/* The source for a command */
class CoreExport CommandSource final
{
/* The nick executing the command */
Anope::string nick;
/* User executing the command, may be NULL */
Reference<User> u;
public:
/* The account executing the command */
Reference<NickCore> nc;
/* for web clients */
Anope::string ip;
/* Where the reply should go */
CommandReply *reply;
/* Channel the command was executed on (fantasy) */
Reference<Channel> c = nullptr;
/* The service this command is on */
Reference<BotInfo> service;
/* The actual name of the command being executed */
Anope::string command;
/* The permission of the command being executed */
Anope::string permission;
/* The unique identifier of the executing message. */
Anope::string msgid;
CommandSource(const Anope::string &n, User *user, NickCore *core, CommandReply *reply, BotInfo *bi, const Anope::string &m = "");
const Anope::string &GetNick() const;
User *GetUser();
NickCore *GetAccount();
AccessGroup AccessFor(ChannelInfo *ci);
bool IsFounder(ChannelInfo *ci);
void Reply(const char *message, ...) ATTR_FORMAT(2, 3);
void Reply(const Anope::string &message);
bool HasCommand(const Anope::string &cmd);
bool HasPriv(const Anope::string &cmd);
bool IsServicesOper();
bool IsOper();
};
/** Every services command is a class, inheriting from Command.
*/
class CoreExport Command
: public Service
{
Anope::string desc;
std::vector<Anope::string> syntax;
/* Allow unregistered users to use this command */
bool allow_unregistered;
/* Command requires that a user is executing it */
bool require_user;
public:
/* Maximum parameters accepted by this command */
size_t max_params;
/* Minimum parameters required to use this command */
size_t min_params;
/* Module which owns us */
Module *module;
protected:
/** Create a new command.
* @param owner The owner of the command
* @param sname The command name
* @param min_params The minimum number of parameters the parser will require to execute this command
* @param max_params The maximum number of parameters the parser will create, after max_params, all will be combined into the last argument.
* NOTE: If max_params is not set (default), there is no limit to the max number of params.
*/
Command(Module *owner, const Anope::string &sname, size_t min_params, size_t max_params = 0);
public:
virtual ~Command() = default;
protected:
void SetDesc(const Anope::string &d);
void ClearSyntax();
void SetSyntax(const Anope::string &s);
void SendSyntax(CommandSource &);
void AllowUnregistered(bool b);
void RequireUser(bool b);
public:
bool AllowUnregistered() const;
bool RequireUser() const;
/** Get the command description
* @param source The source wanting the command description
* @return The commands description
*/
virtual const Anope::string GetDesc(CommandSource &source) const;
/** Execute this command.
* @param source The source
* @param params Command parameters
*/
virtual void Execute(CommandSource &source, const std::vector<Anope::string> ¶ms) = 0;
/** Called when HELP is requested for the client this command is on.
* @param source The source
*/
virtual void OnServHelp(CommandSource &source);
/** Requested when the user is requesting help on this command. Help on this command should be sent to the user.
* @param source The source
* @param subcommand The subcommand the user is requesting help on, or an empty string. (e.g. /ns help set foo bar lol gives a subcommand of "FOO BAR LOL")
* @return true if help was provided to the user, false otherwise.
*/
virtual bool OnHelp(CommandSource &source, const Anope::string &subcommand);
/** Requested when the user provides bad syntax to this command (not enough params, etc).
* @param source The source
* @param subcommand The subcommand the user tried to use
*/
virtual void OnSyntaxError(CommandSource &source, const Anope::string &subcommand);
/** Runs a command
* @param source The source of the command
* @param message The full message to run, the command is at the beginning of the message
*/
static void Run(CommandSource &source, const Anope::string &message);
void Run(CommandSource &source, const Anope::string &, const CommandInfo &, std::vector<Anope::string> ¶ms);
/** Looks up a command name from the service name.
* Note that if the same command exists multiple places this will return the first one encountered
* @param command_service The command service to lookup, eg, nickserv/register
* @param bot If found, is set to the bot the command is on, eg NickServ
* @param name If found, is set to the command name, eg REGISTER
* @return true if the given command service exists
*/
static bool FindCommandFromService(const Anope::string &command_service, BotInfo *&bi, Anope::string &name);
};
|