]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/mode.h
17f7e01336486981224e9f35f0f207812750c06e
[user/henk/code/inspircd.git] / include / mode.h
1 /*
2  * InspIRCd -- Internet Relay Chat Daemon
3  *
4  *   Copyright (C) 2013-2016 Attila Molnar <attilamolnar@hush.com>
5  *   Copyright (C) 2012-2013, 2017-2021 Sadie Powell <sadie@witchery.services>
6  *   Copyright (C) 2012 Robby <robby@chatbelgie.be>
7  *   Copyright (C) 2009 Daniel De Graaf <danieldg@inspircd.org>
8  *   Copyright (C) 2008 Thomas Stagner <aquanight@inspircd.org>
9  *   Copyright (C) 2007-2008 Robin Burchell <robin+git@viroteck.net>
10  *   Copyright (C) 2007 Dennis Friis <peavey@inspircd.org>
11  *   Copyright (C) 2006-2008, 2010 Craig Edwards <brain@inspircd.org>
12  *
13  * This file is part of InspIRCd.  InspIRCd is free software: you can
14  * redistribute it and/or modify it under the terms of the GNU General Public
15  * License as published by the Free Software Foundation, version 2.
16  *
17  * This program is distributed in the hope that it will be useful, but WITHOUT
18  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
20  * details.
21  *
22  * You should have received a copy of the GNU General Public License
23  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
24  */
25
26
27 #pragma once
28
29 #include "ctables.h"
30 #include "modechange.h"
31
32 /**
33  * Holds the values for different type of modes
34  * that can exist, USER or CHANNEL type.
35  */
36 enum ModeType
37 {
38         /** User mode */
39         MODETYPE_USER = 0,
40         /** Channel mode */
41         MODETYPE_CHANNEL = 1
42 };
43
44 /**
45  * Holds mode actions - modes can be allowed or denied.
46  */
47 enum ModeAction
48 {
49         MODEACTION_DENY = 0, /* Drop the mode change, AND a parameter if its a parameterized mode */
50         MODEACTION_ALLOW = 1 /* Allow the mode */
51 };
52
53 /**
54  * These fixed values can be used to proportionally compare module-defined prefixes to known values.
55  * For example, if your module queries a Channel, and is told that user 'joebloggs' has the prefix
56  * '$', and you dont know what $ means, then you can compare it to these three values to determine
57  * its worth against them. For example if '$' had a value of 15000, you would know it is of higher
58  * status than voice, but lower status than halfop.
59  * No two modes should have equal prefix values.
60  */
61 enum PrefixModeValue
62 {
63         /* +v */
64         VOICE_VALUE     =       10000,
65         /* +h */
66         HALFOP_VALUE    =       20000,
67         /* +o */
68         OP_VALUE        =       30000
69 };
70
71 enum ParamSpec
72 {
73         /** No parameters */
74         PARAM_NONE,
75         /** Parameter required on mode setting only */
76         PARAM_SETONLY,
77         /** Parameter always required */
78         PARAM_ALWAYS
79 };
80
81 class PrefixMode;
82 class ListModeBase;
83 class ParamModeBase;
84
85 /** Each mode is implemented by ONE ModeHandler class.
86  * You must derive ModeHandler and add the child class to
87  * the list of modes handled by the ircd, using
88  * ModeParser::AddMode. When the mode you implement is
89  * set by a user, the virtual function OnModeChange is
90  * called. If you specify a value greater than 0 for
91  * parameters_on or parameters_off, then when the mode is
92  * set or unset respectively, std::string &parameter will
93  * contain the parameter given by the user, else it will
94  * contain an empty string. You may alter this parameter
95  * string, and if you alter it to an empty string, and your
96  * mode is expected to have a parameter, then this is
97  * equivalent to returning MODEACTION_DENY.
98  */
99 class CoreExport ModeHandler : public ServiceProvider
100 {
101  public:
102         typedef size_t Id;
103
104         enum Class
105         {
106                 MC_PREFIX,
107                 MC_LIST,
108                 MC_PARAM,
109                 MC_OTHER
110         };
111
112  private:
113         /** The opaque id of this mode assigned by the mode parser
114          */
115         Id modeid;
116
117  protected:
118         /** What kind of parameters does the mode take?
119          */
120         ParamSpec parameters_taken;
121
122         /**
123          * The mode letter you're implementing.
124          */
125         char mode;
126
127         /**
128          * True if the mode requires oper status
129          * to set.
130          */
131         bool oper;
132
133         /**
134          * Mode is a 'list' mode. The behaviour
135          * of your mode is now set entirely within
136          * the class as of the 1.1 api, rather than
137          * inside the mode parser as in the 1.0 api,
138          * so the only use of this value (along with
139          * IsListMode()) is for the core to determine
140          * whether your module can produce 'lists' or not
141          * (e.g. banlists, etc)
142          */
143         bool list;
144
145         /**
146          * The mode type, either MODETYPE_USER or
147          * MODETYPE_CHANNEL.
148          */
149         ModeType m_type;
150
151         /** The object type of this mode handler
152          */
153         const Class type_id;
154
155         /** The prefix rank required to set this mode on channels. */
156         unsigned int ranktoset;
157
158         /** The prefix rank required to unset this mode on channels. */
159         unsigned int ranktounset;
160
161         /** If non-empty then the syntax of the parameter for this mode. */
162         std::string syntax;
163
164  public:
165         /**
166          * The constructor for ModeHandler initializes the mode handler.
167          * The constructor of any class you derive from ModeHandler should
168          * probably call this constructor with the parameters set correctly.
169          * @param me The module which created this mode
170          * @param name A one-word name for the mode
171          * @param modeletter The mode letter you wish to handle
172          * @param params Parameters taken by the mode
173          * @param type Type of the mode (MODETYPE_USER or MODETYPE_CHANNEL)
174          * @param mclass The object type of this mode handler, one of ModeHandler::Class
175          */
176         ModeHandler(Module* me, const std::string& name, char modeletter, ParamSpec params, ModeType type, Class mclass = MC_OTHER);
177         CullResult cull() CXX11_OVERRIDE;
178         virtual ~ModeHandler();
179
180         /** Register this object in the ModeParser
181          */
182         void RegisterService() CXX11_OVERRIDE;
183
184         /**
185          * Returns true if the mode is a list mode
186          */
187         bool IsListMode() const { return list; }
188
189         /**
190          * Check whether this mode is a prefix mode
191          * @return non-NULL if this mode is a prefix mode, NULL otherwise
192          */
193         PrefixMode* IsPrefixMode();
194
195         /**
196          * Check whether this mode is a prefix mode
197          * @return non-NULL if this mode is a prefix mode, NULL otherwise
198          */
199         const PrefixMode* IsPrefixMode() const;
200
201         /**
202          * Check whether this mode handler inherits from ListModeBase
203          * @return non-NULL if this mode handler inherits from ListModeBase, NULL otherwise
204          */
205         ListModeBase* IsListModeBase();
206
207         /**
208          * Check whether this mode handler inherits from ListModeBase
209          * @return non-NULL if this mode handler inherits from ListModeBase, NULL otherwise
210          */
211         const ListModeBase* IsListModeBase() const;
212
213         /**
214          * Check whether this mode handler inherits from ParamModeBase
215          * @return non-NULL if this mode handler inherits from ParamModeBase, NULL otherwise
216          */
217         ParamModeBase* IsParameterMode();
218
219         /**
220          * Check whether this mode handler inherits from ParamModeBase
221          * @return non-NULL if this mode handler inherits from ParamModeBase, NULL otherwise
222          */
223         const ParamModeBase* IsParameterMode() const;
224
225         /**
226          * Returns the mode's type
227          */
228         inline ModeType GetModeType() const { return m_type; }
229         /**
230          * Returns true if the mode can only be set/unset by an oper
231          */
232         inline bool NeedsOper() const { return oper; }
233         /**
234          * Check if the mode needs a parameter for adding or removing
235          * @param adding True to check if the mode needs a parameter when setting, false to check if the mode needs a parameter when unsetting
236          * @return True if the mode needs a parameter for the specified action, false if it doesn't
237          */
238         bool NeedsParam(bool adding) const;
239         /**
240          * Returns the mode character this handler handles.
241          * @return The mode character
242          */
243         char GetModeChar() const { return mode; }
244
245         /** Return the id of this mode which is used in User::modes and
246          * Channel::modes as the index to determine whether a mode is set.
247          */
248         Id GetId() const { return modeid; }
249
250         /** For user modes, return the current parameter, if any
251          */
252         virtual std::string GetUserParameter(const User* user) const;
253
254         /**
255          * Called when a channel mode change access check for your mode occurs.
256          * @param source Contains the user setting the mode.
257          * @param channel contains the destination channel the modes are being set on.
258          * @param parameter The parameter for your mode. This is modifiable.
259          * @param adding This value is true when the mode is being set, or false when it is being unset.
260          * @return allow, deny, or passthru to check against the required level
261          */
262         virtual ModResult AccessCheck(User* source, Channel* channel, std::string &parameter, bool adding);
263
264         /**
265          * Called when a mode change for your mode occurs.
266          * @param source Contains the user setting the mode.
267          * @param dest For usermodes, contains the destination user the mode is being set on. For channelmodes, this is an undefined value.
268          * @param channel For channel modes, contains the destination channel the modes are being set on. For usermodes, this is an undefined value.
269          * @param parameter The parameter for your mode, if you indicated that your mode requires a parameter when being set or unset. Note that
270          * if you alter this value, the new value becomes the one displayed and send out to the network, also, if you set this to an empty string
271          * but you specified your mode REQUIRES a parameter, this is equivalent to returning MODEACTION_DENY and will prevent the mode from being
272          * displayed.
273          * @param adding This value is true when the mode is being set, or false when it is being unset.
274          * @return MODEACTION_ALLOW to allow the mode, or MODEACTION_DENY to prevent the mode, also see the description of 'parameter'.
275          */
276         virtual ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string &parameter, bool adding); /* Can change the mode parameter as its a ref */
277
278         /**
279          * If your mode is a listmode, then this method will be called for displaying an item list, e.g. on MODE \#channel +modechar
280          * without any parameter or other modes in the command.
281          * @param user The user issuing the command
282          * @param channel The channel they're requesting an item list of (e.g. a banlist, or an exception list etc)
283          */
284         virtual void DisplayList(User* user, Channel* channel);
285
286         /** In the event that the mode should be given a parameter, and no parameter was provided, this method is called.
287          * This allows you to give special information to the user, or handle this any way you like.
288          * @param user The user issuing the mode change
289          * @param dest For user mode changes, the target of the mode. For channel mode changes, NULL.
290          * @param channel For channel mode changes, the target of the mode. For user mode changes, NULL.
291          */
292         virtual void OnParameterMissing(User* user, User* dest, Channel* channel);
293
294         /** Called when a user attempts to set a mode and the parameter is invalid.
295          * @param user The user issuing the mode change
296          * @param targetchannel Either the channel target or NULL if changing a user mode.
297          * @param targetuser Either the user target or NULL if changing a channel mode.
298          * @param parameter The invalid parameter.
299          */
300         virtual void OnParameterInvalid(User* user, Channel* targetchannel, User* targetuser, const std::string& parameter);
301
302
303         /**
304          * If your mode is a listmode, this method will be called to display an empty list (just the end of list numeric)
305          * @param user The user issuing the command
306          * @param channel The channel they're requesting an item list of (e.g. a banlist, or an exception list etc)
307          */
308         virtual void DisplayEmptyList(User* user, Channel* channel);
309
310         /**
311          * If your mode needs special action during a server sync to determine which side wins when comparing timestamps,
312          * override this function and use it to return true or false. The default implementation just returns true if
313          * theirs < ours. This will only be called for non-listmodes with parameters, when adding the mode and where
314          * theirs == ours (therefore the default implementation will always return false).
315          * @param their_param Their parameter if the mode has a parameter
316          * @param our_param Our parameter if the mode has a parameter
317          * @param channel The channel we are checking against
318          * @return True if the other side wins the merge, false if we win the merge for this mode.
319          */
320         virtual bool ResolveModeConflict(std::string &their_param, const std::string &our_param, Channel* channel);
321
322         /**
323          * When a MODETYPE_USER mode handler is being removed, the core will call this method for every user on the server.
324          * The usermode will be removed using the appropriate server mode using InspIRCd::SendMode().
325          * @param user The user which the server wants to remove your mode from
326          */
327         void RemoveMode(User* user);
328
329         /**
330          * When a MODETYPE_CHANNEL mode handler is being removed, the server will call this method for every channel on the server.
331          * The mode handler has to populate the given modestacker with mode changes that remove the mode from the channel.
332          * The default implementation of this method can remove all kinds of channel modes except listmodes.
333          * In the case of listmodes, the entire list of items must be added to the modestacker (which is handled by ListModeBase,
334          * so if you inherit from it or your mode can be removed by the default implementation then you do not have to implement
335          * this function).
336          * @param channel The channel which the server wants to remove your mode from
337          * @param changelist Mode change list to populate with the removal of this mode
338          */
339         virtual void RemoveMode(Channel* channel, Modes::ChangeList& changelist);
340
341         /** Retrieves the level required to modify this mode.
342          * @param adding Whether the mode is being added or removed.
343          */
344         inline unsigned int GetLevelRequired(bool adding) const
345         {
346                 return adding ? ranktoset : ranktounset;
347         }
348
349         /** Retrieves the syntax of the parameter for this mode. */
350         const std::string& GetSyntax() const { return syntax; }
351
352         friend class ModeParser;
353 };
354
355 /**
356  * Prefix modes are channel modes that grant a specific rank to members having prefix mode set.
357  * They require a parameter when setting and unsetting; the parameter is always a member of the channel.
358  * A prefix mode may be set on any number of members on a channel, but for a given member a given prefix
359  * mode is either set or not set, in other words members cannot have the same prefix mode set more than once.
360  *
361  * A rank of a member is defined as the rank given by the 'strongest' prefix mode that member has.
362  * Other parts of the IRCd use this rank to determine whether a channel action is allowable for a user or not.
363  * The rank of a prefix mode is constant, i.e. the same rank value is given to all users having that prefix mode set.
364  *
365  * Note that it is possible that the same action requires a different rank on a different channel;
366  * for example changing the topic on a channel having +t set requires a rank that is >= than the rank of a halfop,
367  * but there is no such restriction when +t isn't set.
368  */
369 class CoreExport PrefixMode : public ModeHandler
370 {
371  protected:
372         /** The prefix character granted by this mode. '@' for op, '+' for voice, etc.
373          * If 0, this mode does not have a visible prefix character.
374          */
375         char prefix;
376
377         /** The prefix rank of this mode, used to compare prefix
378          * modes
379          */
380         unsigned int prefixrank;
381
382         /** Whether a client with this prefix can remove it from themself. */
383         bool selfremove;
384
385  public:
386         /**
387          * Constructor
388          * @param Creator The module creating this mode
389          * @param Name The user-friendly one word name of the prefix mode, e.g.: "op", "voice"
390          * @param ModeLetter The mode letter of this mode
391          * @param Rank Rank given by this prefix mode, see explanation above
392          * @param PrefixChar Prefix character, or 0 if the mode has no prefix character
393          */
394         PrefixMode(Module* Creator, const std::string& Name, char ModeLetter, unsigned int Rank = 0, char PrefixChar = 0);
395
396         /**
397          * Called when a channel mode change access check for your mode occurs.
398          * @param source Contains the user setting the mode.
399          * @param channel contains the destination channel the modes are being set on.
400          * @param parameter The parameter for your mode. This is modifiable.
401          * @param adding This value is true when the mode is being set, or false when it is being unset.
402          * @return allow, deny, or passthru to check against the required level
403          */
404         ModResult AccessCheck(User* source, Channel* channel, std::string &parameter, bool adding) CXX11_OVERRIDE;
405
406         /**
407          * Handles setting and unsetting the prefix mode.
408          * Finds the given member of the given channel, if it's not found an error message is sent to 'source'
409          * and MODEACTION_DENY is returned. Otherwise the mode change is attempted.
410          * @param source Source of the mode change, an error message is sent to this user if the target is not found
411          * @param dest Unused
412          * @param channel The channel the mode change is happening on
413          * @param param The nickname or uuid of the target user
414          * @param adding True when the mode is being set, false when it is being unset
415          * @return MODEACTION_ALLOW if the change happened, MODEACTION_DENY if no change happened
416          * The latter occurs either when the member cannot be found or when the member already has this prefix set
417          * (when setting) or doesn't have this prefix set (when unsetting).
418          */
419         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& param, bool adding) CXX11_OVERRIDE;
420
421         /**
422          * Updates the configuration of this prefix.
423          * @param rank The prefix rank of this mode.
424          * @param setrank The prefix rank required to set this mode on channels.
425          * @param unsetrank The prefix rank required to set this unmode on channels.
426          * @param selfrm Whether a client with this prefix can remove it from themself.
427          */
428         void Update(unsigned int rank, unsigned int setrank, unsigned int unsetrank, bool selfrm);
429
430         /**
431          * Removes this prefix mode from all users on the given channel
432          * @param channel The channel which the server wants to remove your mode from
433          * @param changelist Mode change list to populate with the removal of this mode
434          */
435         void RemoveMode(Channel* channel, Modes::ChangeList& changelist) CXX11_OVERRIDE;
436
437
438         /**
439         * Determines whether a user with this prefix mode can remove it.
440         */
441         bool CanSelfRemove() const { return selfremove; }
442
443         /**
444          * Mode prefix or 0. If this is defined, you should
445          * also implement GetPrefixRank() to return an integer
446          * value for this mode prefix.
447          */
448         char GetPrefix() const { return prefix; }
449
450         /**
451          * Get the 'value' of this modes prefix.
452          * determines which to display when there are multiple.
453          * The mode with the highest value is ranked first. See the
454          * PrefixModeValue enum and Channel::GetPrefixValue() for
455          * more information.
456          */
457         unsigned int GetPrefixRank() const { return prefixrank; }
458 };
459
460 /** A prebuilt mode handler which handles a simple user mode, e.g. no parameters, usable by any user, with no extra
461  * behaviour to the mode beyond the basic setting and unsetting of the mode, not allowing the mode to be set if it
462  * is already set and not allowing it to be unset if it is already unset.
463  * An example of a simple user mode is user mode +w.
464  */
465 class CoreExport SimpleUserModeHandler : public ModeHandler
466 {
467  public:
468         SimpleUserModeHandler(Module* Creator, const std::string& Name, char modeletter, bool operonly = false)
469                 : ModeHandler(Creator, Name, modeletter, PARAM_NONE, MODETYPE_USER)
470         {
471                 oper = operonly;
472         }
473
474         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE;
475 };
476
477 /** A prebuilt mode handler which handles a simple channel mode, e.g. no parameters, usable by any user, with no extra
478  * behaviour to the mode beyond the basic setting and unsetting of the mode, not allowing the mode to be set if it
479  * is already set and not allowing it to be unset if it is already unset.
480  * An example of a simple channel mode is channel mode +s.
481  */
482 class CoreExport SimpleChannelModeHandler : public ModeHandler
483 {
484  public:
485         SimpleChannelModeHandler(Module* Creator, const std::string& Name, char modeletter, bool operonly = false)
486                 : ModeHandler(Creator, Name, modeletter, PARAM_NONE, MODETYPE_CHANNEL)
487         {
488                 oper = operonly;
489         }
490
491         ModeAction OnModeChange(User* source, User* dest, Channel* channel, std::string& parameter, bool adding) CXX11_OVERRIDE;
492 };
493
494 /**
495  * The ModeWatcher class can be used to alter the behaviour of a mode implemented
496  * by the core or by another module. To use ModeWatcher, derive a class from it,
497  * and attach it to the mode using Server::AddModeWatcher and Server::DelModeWatcher.
498  * A ModeWatcher will be called both before and after the mode change.
499  */
500 class CoreExport ModeWatcher : public classbase
501 {
502  private:
503         /**
504          * The mode name this class is watching
505          */
506         const std::string mode;
507
508         /**
509          * The mode type being watched (user or channel)
510          */
511         ModeType m_type;
512
513  public:
514         ModuleRef creator;
515         /**
516          * The constructor initializes the mode and the mode type
517          */
518         ModeWatcher(Module* creator, const std::string& modename, ModeType type);
519         /**
520          * The default destructor does nothing.
521          */
522         virtual ~ModeWatcher();
523
524         /**
525          * Get the mode name being watched
526          * @return The mode name being watched
527          */
528         const std::string& GetModeName() const { return mode; }
529
530         /**
531          * Get the mode type being watched
532          * @return The mode type being watched (user or channel)
533          */
534         ModeType GetModeType() const { return m_type; }
535
536         /**
537          * Before the mode character is processed by its handler, this method will be called.
538          * @param source The sender of the mode
539          * @param dest The target user for the mode, if you are watching a user mode
540          * @param channel The target channel for the mode, if you are watching a channel mode
541          * @param parameter The parameter of the mode, if the mode is supposed to have a parameter.
542          * If you alter the parameter you are given, the mode handler will see your atered version
543          * when it handles the mode.
544          * @param adding True if the mode is being added and false if it is being removed
545          * @return True to allow the mode change to go ahead, false to abort it. If you abort the
546          * change, the mode handler (and ModeWatcher::AfterMode()) will never see the mode change.
547          */
548         virtual bool BeforeMode(User* source, User* dest, Channel* channel, std::string& parameter, bool adding);
549         /**
550          * After the mode character has been processed by the ModeHandler, this method will be called.
551          * @param source The sender of the mode
552          * @param dest The target user for the mode, if you are watching a user mode
553          * @param channel The target channel for the mode, if you are watching a channel mode
554          * @param parameter The parameter of the mode, if the mode is supposed to have a parameter.
555          * You cannot alter the parameter here, as the mode handler has already processed it.
556          * @param adding True if the mode is being added and false if it is being removed
557          */
558         virtual void AfterMode(User* source, User* dest, Channel* channel, const std::string& parameter, bool adding);
559 };
560
561 /** The mode parser handles routing of modes and handling of mode strings.
562  * It marshalls, controls and maintains both ModeWatcher and ModeHandler classes,
563  * parses client to server MODE strings for user and channel modes, and performs
564  * processing for the 004 mode list numeric, amongst other things.
565  */
566 class CoreExport ModeParser : public fakederef<ModeParser>
567 {
568  public:
569         /** The maximum number of modes which can be created. */
570         static const ModeHandler::Id MODEID_MAX = 64;
571
572         /** The maximum length of a mode parameter. */
573         static const size_t MODE_PARAM_MAX = 250;
574
575         /** Type of the container that maps mode names to ModeHandlers
576          */
577         typedef TR1NS::unordered_map<std::string, ModeHandler*, irc::insensitive, irc::StrHashComp> ModeHandlerMap;
578
579  private:
580         /** Type of the container that maps mode names to ModeWatchers
581          */
582         typedef insp::flat_multimap<std::string, ModeWatcher*> ModeWatcherMap;
583
584         /** Last item in the ModeType enum
585          */
586         static const unsigned int MODETYPE_LAST = 2;
587
588         /** Mode handlers for each mode, to access a handler subtract
589          * 65 from the ascii value of the mode letter.
590          * The upper bit of the value indicates if its a usermode
591          * or a channel mode, so we have 256 of them not 64.
592          */
593         ModeHandler* modehandlers[MODETYPE_LAST][128];
594
595         /** An array of mode handlers indexed by the mode id
596          */
597         ModeHandler* modehandlersbyid[MODETYPE_LAST][MODEID_MAX];
598
599         /** A map of mode handlers keyed by their name
600          */
601         ModeHandlerMap modehandlersbyname[MODETYPE_LAST];
602
603         /** Lists of mode handlers by type
604          */
605         struct
606         {
607                 /** List of mode handlers that inherit from ListModeBase
608                  */
609                 std::vector<ListModeBase*> list;
610
611                 /** List of mode handlers that inherit from PrefixMode
612                  */
613                 std::vector<PrefixMode*> prefix;
614         } mhlist;
615
616         /** Mode watcher classes
617          */
618         ModeWatcherMap modewatchermap;
619
620         /** Last processed mode change
621          */
622         Modes::ChangeList LastChangeList;
623
624         /**
625          * Attempts to apply a mode change to a user or channel
626          */
627         ModeAction TryMode(User* user, User* targu, Channel* targc, Modes::Change& mcitem, bool SkipACL);
628
629         /** Allocates an unused id for the given mode type, throws a ModuleException if out of ids.
630          * @param mt The type of the mode to allocate the id for
631          * @return The id
632          */
633         ModeHandler::Id AllocateModeId(ModeType mt);
634
635  public:
636         typedef std::vector<ListModeBase*> ListModeList;
637         typedef std::vector<PrefixMode*> PrefixModeList;
638
639         typedef unsigned int ModeProcessFlag;
640         enum ModeProcessFlags
641         {
642                 /** If only this flag is specified, the mode change will be global
643                  * and parameter modes will have their parameters explicitly set
644                  * (not merged). This is the default.
645                  */
646                 MODE_NONE = 0,
647
648                 /** If this flag is set then the parameters of non-listmodes will be
649                  * merged according to their conflict resolution rules.
650                  * Does not affect user modes, channel modes without a parameter and
651                  * listmodes.
652                  */
653                 MODE_MERGE = 1,
654
655                 /** If this flag is set then the linking module will ignore the mode change
656                  * and not send it to other servers. The mode change will be processed
657                  * locally and sent to local user(s) as usual.
658                  */
659                 MODE_LOCALONLY = 2,
660
661                 /** If this flag is set then the mode change will be subject to access checks.
662                  * For more information see the documentation of the PrefixMode class,
663                  * ModeHandler::ranktoset and ModeHandler::AccessCheck().
664                  * Modules may explicitly allow a mode change regardless of this flag by returning
665                  * MOD_RES_ALLOW from the OnPreMode hook. Only affects channel mode changes.
666                  */
667                 MODE_CHECKACCESS = 4
668         };
669
670         ModeParser();
671         ~ModeParser();
672
673         static bool IsModeChar(char chr);
674
675         /** Tidy a banmask. This makes a banmask 'acceptable' if fields are left out.
676          * E.g.
677          *
678          * nick -> nick!*@*
679          *
680          * nick!ident -> nick!ident@*
681          *
682          * host.name -> *!*\@host.name
683          *
684          * ident@host.name -> *!ident\@host.name
685          *
686          * This method can be used on both IPV4 and IPV6 user masks.
687          */
688         static void CleanMask(std::string &mask);
689
690         /** Gets the last mode change to be processed. */
691         const Modes::ChangeList& GetLastChangeList() const { return LastChangeList; }
692
693         /** Add a mode to the mode parser.
694          * Throws a ModuleException if the mode cannot be added.
695          */
696         void AddMode(ModeHandler* mh);
697
698         /** Delete a mode from the mode parser.
699          * When a mode is deleted, the mode handler will be called
700          * for every user (if it is a user mode) or for every  channel
701          * (if it is a channel mode) to unset the mode on all objects.
702          * This prevents modes staying in the system which no longer exist.
703          * @param mh The mode handler to remove
704          * @return True if the mode was successfully removed.
705          */
706         bool DelMode(ModeHandler* mh);
707
708         /** Add a mode watcher.
709          * A mode watcher is triggered before and after a mode handler is
710          * triggered. See the documentation of class ModeWatcher for more
711          * information.
712          * @param mw The ModeWatcher you want to add
713          */
714         void AddModeWatcher(ModeWatcher* mw);
715
716         /** Delete a mode watcher.
717          * A mode watcher is triggered before and after a mode handler is
718          * triggered. See the documentation of class ModeWatcher for more
719          * information.
720          * @param mw The ModeWatcher you want to delete
721          * @return True if the ModeWatcher was deleted correctly
722          */
723         bool DelModeWatcher(ModeWatcher* mw);
724
725         /** Process a list of mode changes entirely. If the mode changes do not fit into one MODE line
726          * then multiple MODE lines are generated.
727          * @param user The source of the mode change, can be a server user.
728          * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel.
729          * @param targetuser User to apply the mode change on. NULL if changing modes on a user.
730          * @param changelist Modes to change in form of a Modes::ChangeList.
731          * @param flags Optional flags controlling how the mode change is processed,
732          * defaults to MODE_NONE.
733          */
734         void Process(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE);
735
736         /** Process a single MODE line's worth of mode changes, taking max modes and line length limits
737          * into consideration. Return value indicates how many modes were processed.
738          * @param user The source of the mode change, can be a server user.
739          * @param targetchannel Channel to apply the mode change on. NULL if changing modes on a channel.
740          * @param targetuser User to apply the mode change on. NULL if changing modes on a user.
741          * @param changelist Modes to change in form of a Modes::ChangeList. May not process
742          * the entire list due to MODE line length and max modes limitations.
743          * @param flags Optional flags controlling how the mode change is processed,
744          * defaults to MODE_NONE.
745          * @param beginindex Index of the first element in changelist to process. Mode changes before
746          * the element with this index are ignored.
747          * @return Number of mode changes processed from changelist.
748          */
749         unsigned int ProcessSingle(User* user, Channel* targetchannel, User* targetuser, Modes::ChangeList& changelist, ModeProcessFlag flags = MODE_NONE, unsigned int beginindex = 0);
750
751         /** Turn a list of parameters compatible with the format of the MODE command into
752          * Modes::ChangeList form. All modes are processed, regardless of max modes. Unknown modes
753          * are skipped.
754          * @param user The source of the mode change, can be a server user. Error numerics are sent to
755          * this user.
756          * @param type MODETYPE_USER if this is a user mode change or MODETYPE_CHANNEL if this
757          * is a channel mode change.
758          * @param parameters List of strings describing the mode change to convert to a ChangeList.
759          * Must be using the same format as the parameters of a MODE command.
760          * @param changelist ChangeList object to populate.
761          * @param beginindex Index of the first element that is part of the MODE list in the parameters
762          * container. Defaults to 1.
763          * @param endindex Index of the first element that is not part of the MODE list. By default,
764          * the entire container is considered part of the MODE list.
765          */
766         void ModeParamsToChangeList(User* user, ModeType type, const std::vector<std::string>& parameters, Modes::ChangeList& changelist, unsigned int beginindex = 1, unsigned int endindex = UINT_MAX);
767
768         /** Find the mode handler for a given mode name and type.
769          * @param modename The mode name to search for.
770          * @param mt Type of mode to search for, user or channel.
771          * @return A pointer to a ModeHandler class, or NULL of there isn't a handler for the given mode name.
772          */
773         ModeHandler* FindMode(const std::string& modename, ModeType mt);
774
775         /** Find the mode handler for a given mode and type.
776          * @param modeletter mode letter to search for
777          * @param mt type of mode to search for, user or channel
778          * @returns a pointer to a ModeHandler class, or NULL of there isn't a handler for the given mode
779          */
780         ModeHandler* FindMode(unsigned const char modeletter, ModeType mt);
781
782         /** Find the mode handler for the given prefix mode
783          * @param modeletter The mode letter to search for
784          * @return A pointer to the PrefixMode or NULL if the mode wasn't found or it isn't a prefix mode
785          */
786         PrefixMode* FindPrefixMode(unsigned char modeletter);
787
788         /** Find a mode handler by its prefix.
789          * If there is no mode handler with the given prefix, NULL will be returned.
790          * @param pfxletter The prefix to find, e.g. '@'
791          * @return The mode handler which handles this prefix, or NULL if there is none.
792          */
793         PrefixMode* FindPrefix(unsigned const char pfxletter);
794
795         /** Generates a list of modes, comma separated by type:
796          *  1; Listmodes EXCEPT those with a prefix
797          *  2; Modes that take a param when adding or removing
798          *  3; Modes that only take a param when adding
799          *  4; Modes that dont take a param
800          */
801         std::string GiveModeList(ModeType mt);
802
803         /** This returns the PREFIX=(ohv)@%+ section of the 005 numeric, or
804          * just the "@%+" part if the parameter false
805          */
806         std::string BuildPrefixes(bool lettersAndModes = true);
807
808         /** Get a list of all mode handlers that inherit from ListModeBase
809          * @return A list containing ListModeBase modes
810          */
811         const ListModeList& GetListModes() const { return mhlist.list; }
812
813         /** Get a list of all prefix modes
814          * @return A list containing all prefix modes
815          */
816         const PrefixModeList& GetPrefixModes() const { return mhlist.prefix; }
817
818         /** Get a mode name -> ModeHandler* map containing all modes of the given type
819          * @param mt Type of modes to return, MODETYPE_USER or MODETYPE_CHANNEL
820          * @return A map of mode handlers of the given type
821          */
822         const ModeHandlerMap& GetModes(ModeType mt) const { return modehandlersbyname[mt]; }
823
824         /** Show the list of a list mode to a user. Modules can deny the listing.
825          * @param user User to show the list to.
826          * @param chan Channel to show the list of.
827          * @param mh List mode to show the list of.
828          */
829         void ShowListModeList(User* user, Channel* chan, ModeHandler* mh);
830 };
831
832 inline PrefixMode* ModeHandler::IsPrefixMode()
833 {
834         return (this->type_id == MC_PREFIX ? static_cast<PrefixMode*>(this) : NULL);
835 }
836
837 inline const PrefixMode* ModeHandler::IsPrefixMode() const
838 {
839         return (this->type_id == MC_PREFIX ? static_cast<const PrefixMode*>(this) : NULL);
840 }
841
842 inline ListModeBase* ModeHandler::IsListModeBase()
843 {
844         return (this->type_id == MC_LIST ? reinterpret_cast<ListModeBase*>(this) : NULL);
845 }
846
847 inline const ListModeBase* ModeHandler::IsListModeBase() const
848 {
849         return (this->type_id == MC_LIST ? reinterpret_cast<const ListModeBase*>(this) : NULL);
850 }
851
852 inline ParamModeBase* ModeHandler::IsParameterMode()
853 {
854         return (this->type_id == MC_PARAM ? reinterpret_cast<ParamModeBase*>(this) : NULL);
855 }
856
857 inline const ParamModeBase* ModeHandler::IsParameterMode() const
858 {
859         return (this->type_id == MC_PARAM ? reinterpret_cast<const ParamModeBase*>(this) : NULL);
860 }