]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/command_parse.h
Implement IRCv3 message tag support.
[user/henk/code/inspircd.git] / include / command_parse.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2009-2010 Daniel De Graaf <danieldg@inspircd.org>
5  *   Copyright (C) 2007 Robin Burchell <robin+git@viroteck.net>
6  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
7  *   Copyright (C) 2005-2007 Craig Edwards <craigedwards@brainbox.cc>
8  *
9  * This file is part of InspIRCd.  InspIRCd is free software: you can
10  * redistribute it and/or modify it under the terms of the GNU General Public
11  * License as published by the Free Software Foundation, version 2.
12  *
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22
23 #pragma once
24
25 /** This class handles command management and parsing.
26  * It allows you to add and remove commands from the map,
27  * call command handlers by name, and chop up comma seperated
28  * parameters into multiple calls.
29  */
30 class CoreExport CommandParser
31 {
32  public:
33         typedef TR1NS::unordered_map<std::string, Command*, irc::insensitive, irc::StrHashComp> CommandMap;
34
35  private:
36         /** Process a command from a user.
37          * @param user The user to parse the command for.
38          * @param command The name of the command.
39          * @param parameters The parameters to the command.
40          */
41         void ProcessCommand(LocalUser* user, std::string& command, CommandBase::Params& parameters);
42
43         /** Command list, a hash_map of command names to Command*
44          */
45         CommandMap cmdlist;
46
47  public:
48         /** Default constructor.
49          */
50         CommandParser();
51
52         /** Get a command name -> Command* map containing all client to server commands
53          * @return A map of command handlers keyed by command names
54          */
55         const CommandMap& GetCommands() const { return cmdlist; }
56
57         /** Calls the handler for a given command.
58          * @param commandname The command to find. This should be in uppercase.
59          * @param parameters Parameter list
60          * @param user The user to call the handler on behalf of
61          * @param cmd If non-NULL and the command was executed it is set to the command handler,
62          * otherwise it isn't written to.
63          * @return This method will return CMD_SUCCESS if the command handler was found and called,
64          * and the command completeld successfully. It will return CMD_FAILURE if the command handler was found
65          * and called, but the command did not complete successfully, and it will return CMD_INVALID if the
66          * command simply did not exist at all or the wrong number of parameters were given, or the user
67          * was not privilaged enough to execute the command.
68          */
69         CmdResult CallHandler(const std::string& commandname, const CommandBase::Params& parameters, User* user, Command** cmd = NULL);
70
71         /** Get the handler function for a command.
72          * @param commandname The command required. Always use uppercase for this parameter.
73          * @return a pointer to the command handler, or NULL
74          */
75         Command* GetHandler(const std::string &commandname);
76
77         /** LoopCall is used to call a command handler repeatedly based on the contents of a comma seperated list.
78          * There are two ways to call this method, either with one potential list or with two potential lists.
79          * We need to handle two potential lists for JOIN, because a JOIN may contain two lists of items at once:
80          * the channel names and their keys as follows:
81          *
82          * JOIN \#chan1,\#chan2,\#chan3 key1,,key3
83          *
84          * Therefore, we need to deal with both lists concurrently. If there are two lists then the method reads
85          * them both together until the first runs out of tokens.
86          * With one list it is much simpler, and is used in NAMES, WHOIS, PRIVMSG etc.
87          *
88          * If there is only one list and there are duplicates in it, then the command handler is only called for
89          * unique items. Entries are compared using "irc comparison".
90          * If the usemax parameter is true (the default) the function only parses until it reaches
91          * ServerInstance->Config->MaxTargets number of targets, to stop abuse via spam.
92          *
93          * The OnPostCommand hook is executed for each item after it has been processed by the handler, with the
94          * original line parameter being empty (to indicate that the command in that form was created by this function).
95          * This only applies if the user executing the command is local.
96          *
97          * If there are two lists and the second list runs out of tokens before the first list then parameters[extra]
98          * will be an EMPTY string when Handle() is called for the remaining tokens in the first list, even if it is
99          * in the middle of parameters[]! Moreover, empty tokens in the second list are allowed, and those will also
100          * result in the appropiate entry being empty in parameters[].
101          * This is different than what command handlers usually expect; the command parser only allows an empty param
102          * as the last item in the vector.
103          *
104          * @param user The user who sent the command
105          * @param handler The command handler to call for each parameter in the list
106          * @param parameters Parameter list as a vector of strings
107          * @param splithere The first parameter index to split as a comma seperated list
108          * @param extra The second parameter index to split as a comma seperated list, or -1 (the default) if there is only one list
109          * @param usemax True to limit the command to MaxTargets targets (default), or false to process all tokens
110          * @return This function returns true when it identified a list in the given parameter and finished calling the
111          * command handler for each entry on the list. When this occurs, the caller should return without doing anything,
112          * otherwise it should continue into its main section of code.
113          */
114         static bool LoopCall(User* user, Command* handler, const CommandBase::Params& parameters, unsigned int splithere, int extra = -1, bool usemax = true);
115
116         /** Take a raw input buffer from a recvq, and process it on behalf of a user.
117          * @param buffer The buffer line to process
118          * @param user The user to whom this line belongs
119          */
120         void ProcessBuffer(LocalUser* user, const std::string& buffer);
121
122         /** Add a new command to the commands hash
123          * @param f The new Command to add to the list
124          * @return True if the command was added
125          */
126         bool AddCommand(Command *f);
127
128         /** Removes a command.
129          */
130         void RemoveCommand(Command* x);
131
132         /** Translate a single item based on the TranslationType given.
133          * @param to The translation type to use for the process
134          * @param item The input string
135          * @param dest The output string. The translation result will be appended to this string
136          * @param custom_translator Used to translate the parameter if the translation type is TR_CUSTOM, if NULL, TR_CUSTOM will act like TR_TEXT
137          * @param paramnumber The index of the parameter we are translating.
138          */
139         static void TranslateSingleParam(TranslateType to, const std::string& item, std::string& dest, CommandBase* custom_translator = NULL, unsigned int paramnumber = 0);
140
141         /** Translate nicknames in a list of strings into UIDs, based on the TranslateTypes given.
142          * @param to The translation types to use for the process. If this list is too short, TR_TEXT is assumed for the rest.
143          * @param source The strings to translate
144          * @param prefix_final True if the final source argument should have a colon prepended (if it could contain a space)
145          * @param custom_translator Used to translate the parameter if the translation type is TR_CUSTOM, if NULL, TR_CUSTOM will act like TR_TEXT
146          * @return dest The output string
147          */
148         static std::string TranslateUIDs(const std::vector<TranslateType>& to, const CommandBase::Params& source, bool prefix_final = false, CommandBase* custom_translator = NULL);
149 };
150
151 /** A lookup table of values for multiplier characters used by
152  * InspIRCd::Duration(). In this lookup table, the indexes for
153  * the ascii values 'm' and 'M' have the value '60', the indexes
154  * for the ascii values 'D' and 'd' have a value of '86400', etc.
155  */
156 const int duration_multi[] =
157 {
158         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
159         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
160         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
161         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
162         1, 1, 1, 1, 1, 1, 1, 1, 86400, 1, 1, 1, 3600,
163         1, 1, 1, 1, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1,
164         604800, 1, 31557600, 1, 1, 1, 1, 1, 1, 1, 1,
165         1, 1, 86400, 1, 1, 1, 3600, 1, 1, 1, 1, 60,
166         1, 1, 1, 1, 1, 1, 1, 1, 1, 604800, 1, 31557600,
167         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
168         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
169         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
170         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
171         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
172         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
173         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
174         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
175         1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
176 };